Skip to main contentSkip to navigation
    Client API

    HireNewTalent.ai Public API Documentation

    Build end-to-end hiring workflows into your product. Search vetted talent, create engagements, review AI interview scores, send offers, manage lifecycle actions, and message talent through the REST API. The official MCP server exposes the core agent-ready workflow as native tools.

    hnt-api-session
    POST /v1/engagements
    Authorization: Bearer hnt_test_...
    
    {
      "role_title": "Executive VA",
      "next_action": "review_score_then_offer_or_pass",
      "valid_actions": ["offer", "pass", "live-interview"]
    }

    Quickstart

    Make your first request

    All endpoints are versioned under /v1. Authenticate with a bearer API key from the client dashboard.

    Base URL

    https://api.hirenewtalent.ai

    bash
    curl -X POST https://api.hirenewtalent.ai/v1/search \-H "Authorization: Bearer hnt_test_YOUR_API_KEY" \-H "Content-Type: application/json" \-d '{"query": "executive assistant with calendar and travel experience"}'

    Client Dashboard

    Create an API key

    API keys are created from the client dashboard. Start with a test key while building, then create a live key when your integration is ready for production traffic.

    Dashboard path

    /dashboard/api-access
    1. Open API Access. Sign in as a client and choose API Access from the Client Dashboard sidebar.
    2. Choose Test or Live. Test keys use the hnt_test_ prefix and do not require billing. Live keys require a connected billing account.
    3. Name the key. Use a recognizable name such as Local Dev, Staging, or Production.
    4. Generate and copy once. Select Generate Key, copy the plaintext key from the confirmation dialog, and store it in your backend secret manager or environment variables.
    The dashboard only shows the full API key one time. If a key is lost or exposed, revoke it from API Access and generate a replacement.

    Authentication

    Bearer keys and scopes

    API keys are scoped to one client account. Every read and write is automatically limited to that client's data.

    search

    Talent search and profile lookup.

    pricing

    Role-level pricing estimates.

    engagements

    Engagement creation and lifecycle actions.

    messages

    Client/talent conversations over REST.

    talent.interviews.read

    Prior interview history and score review.

    interviews

    Custom interview generation and interview workflows.

    http
    Authorization: Bearer hnt_test_YOUR_API_KEYContent-Type: application/json

    Security best practices

    • Store API keys in a secret manager or backend environment variable.
    • Send keys only in the Authorization header.
    • Never place keys in URLs, browser bundles, analytics payloads, or logs.
    • Rotate keys immediately if a key may have been exposed.

    MCP server

    Native tools for AI agents

    Use the official Model Context Protocol server when your agent runs in Claude Desktop, Cursor, Claude Code, Cline, Codex, or another MCP-capable client. It wraps the full hiring workflow as native tool calls, so agents can search talent, fetch profiles, estimate pricing, review interviews, create engagements, poll the event feed, send offers, message talent, and manage lifecycle actions without writing HTTP plumbing.

    Package

    @hirenewtalentai/mcp-server

    Start with a hnt_test_* key. Test keys exercise the full workflow without sending real notifications or triggering live billing behavior.

    Claude Code — one command

    bash
    claude mcp add hirenewtalent \--env HIRENEWTALENT_API_KEY=hnt_test_YOUR_API_KEY \-- npx -y @hirenewtalentai/mcp-server

    Claude Desktop / Cursor / Cline — config

    json
    {"mcpServers": {"hirenewtalent": {"command": "npx","args": ["-y", "@hirenewtalentai/mcp-server"],"env": {"HIRENEWTALENT_API_KEY": "hnt_test_YOUR_API_KEY"}}}}

    Codex — one command

    bash
    codex mcp add hirenewtalent \--env HIRENEWTALENT_API_KEY=hnt_test_YOUR_API_KEY \-- npx -y @hirenewtalentai/mcp-server

    Codex uses TOML, not JSON — the command above writes an [mcp_servers.hirenewtalent] block to ~/.codex/config.toml.

    Available MCP tools

    search_talentget_talentget_interview_historyget_pricing_estimategenerate_custom_interviewcreate_engagementget_engagementlist_engagementssend_offerpass_on_candidaterequest_live_interviewterminate_engagementrequest_replacementupdate_engagementlist_eventslist_conversationscreate_conversationget_messagessend_messagetest_complete_interviewtest_accept_offertest_decline_offer

    These cover the hiring workflow end to end — search, full profile fetches, pricing, interviews, engagements and lifecycle actions, the events feed, and talent messaging. The same command, args, and env block works across most MCP-aware clients.

    Responses

    Consistent envelopes

    Successful responses return a data object and optional metadata. Errors return a stable machine-readable code and a request ID for support.

    json
    {"data": {"id": "eng_abc123","status": "pending_decision","next_action": "review_score_then_offer_or_pass","valid_actions": ["offer", "pass", "live-interview"]},"meta": {"request_id": "req_abc123","timestamp": "2026-04-13T12:00:00.000Z","environment": "live"}}
    json
    {"error": {"code": "invalid_state_transition","message": "Cannot send offer: engagement is in invited state","request_id": "req_abc123","details": {"current_state": "invited","attempted_action": "offer","valid_actions": []}}}

    Definitions

    Data object fields

    Common fields returned inside API data objects. Some fields appear only on specific resources or lifecycle states.

    FieldTypeDefinition
    idstringUnique identifier for the returned resource. The resource type depends on the endpoint, such as a talent, engagement, conversation, or message.
    full_namestringTalent's display name.
    titlestringTalent profile title or role label, such as Executive VA or Bookkeeper.
    match_scorenumberSearch relevance score from 0 to 1, where higher means a stronger match to the query.
    biostringShort profile summary describing the talent's background and strengths.
    skillsstring[]List of skills, tools, or capabilities associated with the talent profile.
    querystringThe search query submitted to the API.
    total_matchednumberTotal number of profiles that matched the search before result limiting or curation.
    emailstringEmail address associated with a profile when available to the authenticated client.
    avatar_urlstringURL for the talent profile image.
    locationstringTalent's country, city, or general location.
    talent_profilesobjectNested talent profile details including title, skills, experience, availability, rating, and review count.
    talent_experiencesobject[]Work history entries for a talent profile.
    talent_profile_idstringIdentifier of the talent profile used to create an engagement.
    engagement_idstringUnique identifier for an engagement workflow.
    invite_idstringUnique identifier for the AI interview invite connected to an engagement.
    statusstringCurrent lifecycle state of an engagement, such as invited, pending_decision, offer_sent, active, passed, terminated, or completed.
    environmentstringEnvironment associated with the response. Public production workflows return live.
    interview_modestringEngagement creation mode: request_new sends a fresh interview; use_prior_score decides on an existing prior score when available.
    prior_invite_idstringOptional prior interview invite identifier to use when interview_mode is use_prior_score.
    scoreobjectAI interview score data, including overall score, rubric results, strengths, improvements, and summary when available.
    overall_scorenumberAggregate interview score used to summarize candidate fit.
    rubric_resultsobject[]Detailed scoring results for each interview rubric category.
    strengthsstring[]Positive signals identified from the interview.
    improvementsstring[]Areas where the candidate may need support, development, or additional screening.
    summarystringNarrative summary of the interview result or candidate fit.
    english_fluencystringEnglish fluency classification returned with interview results when available.
    next_actionstringMachine-readable hint telling your integration what to do next.
    valid_actionsstring[]List of lifecycle actions currently accepted for the engagement.
    invite_statusstringCurrent status of the interview invite, such as pending or completed.
    own_interviewobjectThe interview commissioned by this engagement, including detailed score data once completed.
    prior_interviewsobject[]Sanitized cross-company prior interview history for the talent, subject to opt-out and privacy stripping.
    engagements_billingobjectBilling cadence and hours associated with an engagement.
    engagement_pricingobjectClient-facing locked price for an engagement after the interview invite is sent: client_rate, client_period_cost, billing_type, and hours_per_period.
    role_titlestringRole being hired for. For AI interview workflows, this should map to a supported role template.
    talent_wage_ratenumberEngine-controlled talent-side hourly rate returned in pricing quotes. Ignored if supplied by callers.
    client_ratenumberEngine-controlled client hourly rate returned in pricing quotes, engagement_pricing, and rate-lock events. Ignored on offer requests.
    hours_per_periodnumberInteger number of hours in the billing period. Valid values depend on billing_type.
    billing_typestringBilling cadence for pricing and engagements. Supported values are monthly_recurring, rolling_4_week, and rolling_biweekly.
    country_regionstringPricing region hint: philippines, india, latin_america, or default.
    start_datestringISO date for the expected engagement start date.
    job_descriptionstringDescription of the work, responsibilities, or outcomes expected for the engagement.
    replacement_requestedbooleanWhether a replacement request was submitted for an active engagement.
    messagestringHuman-readable confirmation or status message.
    conversation_idstringUnique identifier for a client-to-talent conversation.
    messagesobject[]Paginated list of messages in a conversation.
    participant_1_idstringIdentifier for one participant in a conversation.
    participant_2_idstringIdentifier for the other participant in a conversation.
    sender_idstringIdentifier of the user or system that sent a message.
    sender_typestringClassification of the sender, such as human.
    contentstringMessage body text.
    is_readbooleanWhether the message has been marked as read.
    last_message_atstringTimestamp of the most recent message in a conversation.
    last_message_previewstringShort preview of the latest message in a conversation.
    eventsobject[]Paginated engagement event records from the pull-based events feed.
    next_cursorstringOpaque events-feed cursor to pass as since on the next poll.
    has_morebooleanWhether more event pages may be available after the current response.
    created_atstringISO timestamp for when the resource was created.
    updated_atstringISO timestamp for when the resource was last updated.
    limitnumberMaximum number of records returned in a paginated response.
    offsetnumberNumber of records skipped before returning paginated results.

    Reference

    Endpoint overview

    Each endpoint requires the listed permission scope. The API returns 403 forbidden when a key lacks the required scope.

    Health

    Unauthenticated utility endpoint for uptime checks.

    GET

    /health

    Returns status ok and a timestamp. This endpoint is not wrapped in the standard data envelope.

    none

    Example query

    bash
    curl https://api.hirenewtalent.ai/health

    Example output

    json
    {"status": "ok","timestamp": "2026-04-13T12:00:00.000Z"}

    Interview history

    Check whether a talent has already been interviewed for a role before sending a new invite. Responses are privacy-stripped and always return an empty array (never 404) when the talent opts out or does not exist.

    GET

    /v1/talent/:id/interviews

    Privacy-stripped interview history for a talent. Supports role_title, since, and limit query params. Empty histories return uniformly to protect talent privacy.

    talent.interviews.read

    Example query

    bash
    curl "https://api.hirenewtalent.ai/v1/talent/tal_123/interviews?role_title=Executive+Assistant&limit=5" \-H "Authorization: Bearer hnt_test_YOUR_API_KEY"

    Example output

    json
    {"data": {"interviews": [{"invite_id": "inv_prior_123","role_title": "Executive Assistant","completed_at": "2026-04-10T15:30:00.000Z","overall_score": 88,"summary": "Strong calendar ownership and clear client communication."}]}}

    Pricing

    Quote expected costs before committing to an engagement. The pricing engine is the only source of truth — callers cannot override rates.

    GET

    /v1/pricing/estimate

    Role-level price range (entry_standard to senior_expert) without requiring a specific talent.

    pricing

    Example query

    bash
    curl "https://api.hirenewtalent.ai/v1/pricing/estimate?role_title=Bookkeeper&hours_per_period=80&billing_type=monthly_recurring" \-H "Authorization: Bearer hnt_test_YOUR_API_KEY"

    Example output

    json
    {"data": {"role_family": "bookkeeping_accounting","billing_type": "monthly_recurring","hours_per_period": 80,"entry_standard": {"client_rate": 8.25,"client_period_cost": 660},"senior_expert": {"client_rate": 13.5,"client_period_cost": 1080}}}

    Interview generation

    Generate custom interview prompts and rubrics for specialized role titles before creating an engagement. Standard platform roles can go straight to POST /v1/engagements; custom roles should call this endpoint first with persist=true, then create the engagement with the same role_title. Use persist=false only to preview/test the output without saving it.

    When to call this: skip this step for standard platform roles and create the engagement directly. For a custom or specialized role, call this endpoint first with persist: true, then create the engagement with the same role_title. The invite flow will resolve your saved client-scoped prompt and rubric automatically.

    POST

    /v1/interviews/role-config

    Generate an AI interview prompt and rubric for a custom role title before engagement creation. persist=false previews the output without saving; persist=true saves it for later engagements.

    interviews

    Example query

    bash
    curl -X POST "https://api.hirenewtalent.ai/v1/interviews/role-config" \-H "Authorization: Bearer hnt_test_YOUR_API_KEY" \-H "Content-Type: application/json" \-d '{"role_title": "Shopify customer support lead","persist": true}'

    Example output

    json
    {"data": {"role_title": "Shopify customer support lead","prompt": "Assess Shopify support judgment, escalation habits, and customer empathy.","rubric": [{"name": "Platform fluency","weight": 30,"description": "Understands Shopify orders, refunds, subscriptions, apps, and common store admin workflows."},{"name": "Customer communication","weight": 25,"description": "Writes clear, empathetic responses and adapts tone across email, chat, and escalations."},{"name": "Troubleshooting judgment","weight": 20,"description": "Diagnoses customer issues, asks useful follow-up questions, and separates urgent bugs from routine requests."},{"name": "Escalation and ownership","weight": 15,"description": "Knows when to involve operations, engineering, or management while keeping the customer informed."},{"name": "Process improvement","weight": 10,"description": "Identifies repeat issues and suggests macros, help-center updates, or workflow improvements."}],"persisted": {"prompt_template_id": "tpl_prompt_123","rubric_template_id": "tpl_rubric_123","role_mapping_id": "map_123"}}}

    Engagements

    Manage the hiring lifecycle from interview invite through offer, active engagement, replacement, or closeout.

    POST

    /v1/engagements

    Create an engagement. For custom role interviews, first call /v1/interviews/role-config with persist=true, then reuse the same role_title here. request_new sends a fresh AI interview; use_prior_score skips to pending_decision when a prior score exists.

    engagements

    Example query

    bash
    curl -X POST https://api.hirenewtalent.ai/v1/engagements \-H "Authorization: Bearer hnt_test_YOUR_API_KEY" \-H "Content-Type: application/json" \-d '{"talent_profile_id": "tal_123","role_title": "Executive Assistant","interview_mode": "request_new","hours_per_period": 80,"billing_type": "monthly_recurring"}'

    Example output

    json
    {"data": {"id": "eng_123","talent_profile_id": "tal_123","status": "invited","interview_mode": "request_new","next_action": "wait_for_interview_completion","valid_actions": []}}
    GET

    /v1/engagements

    List all engagements for the authenticated client.

    engagements

    Example query

    bash
    curl "https://api.hirenewtalent.ai/v1/engagements?limit=20&offset=0" \-H "Authorization: Bearer hnt_test_YOUR_API_KEY"

    Example output

    json
    {"data": {"engagements": [{"id": "eng_123","status": "pending_decision","role_title": "Executive Assistant","next_action": "review_score_then_offer_or_pass","valid_actions": ["offer", "pass", "live-interview"]}],"limit": 20,"offset": 0}}
    GET

    /v1/engagements/:id

    Retrieve one engagement with score, billing, invite, next_action, and valid_actions.

    engagements

    Example query

    bash
    curl https://api.hirenewtalent.ai/v1/engagements/eng_123 \-H "Authorization: Bearer hnt_test_YOUR_API_KEY"

    Example output

    json
    {"data": {"id": "eng_123","status": "pending_decision","role_title": "Executive Assistant","next_action": "review_score_then_offer_or_pass","valid_actions": ["offer", "pass", "live-interview"],"own_interview": {"overall_score": 88,"summary": "Strong fit for executive support."},"engagement_pricing": {"client_rate": 13,"hours_per_period": 80,"billing_type": "monthly_recurring"}}}
    PATCH

    /v1/engagements/:id

    Update operational metadata such as start_date. Role title and job description are fixed after creation.

    engagements

    Example query

    bash
    curl -X PATCH https://api.hirenewtalent.ai/v1/engagements/eng_123 \-H "Authorization: Bearer hnt_test_YOUR_API_KEY" \-H "Content-Type: application/json" \-d '{"start_date": "2026-05-01"}'

    Example output

    json
    {"data": {"id": "eng_123","start_date": "2026-05-01","updated_at": "2026-04-13T12:00:00.000Z"}}
    POST

    /v1/engagements/:id/offer

    Send an offer using the engine-stamped rate from invite time. No body required; rate fields are ignored.

    engagements

    Example query

    bash
    curl -X POST https://api.hirenewtalent.ai/v1/engagements/eng_123/offer \-H "Authorization: Bearer hnt_test_YOUR_API_KEY"

    Example output

    json
    {"data": {"id": "eng_123","status": "offer_sent","next_action": "wait_for_talent_response","valid_actions": [],"message": "Offer sent."}}
    POST

    /v1/engagements/:id/pass

    Pass on a candidate from the decision stage.

    engagements

    Example query

    bash
    curl -X POST https://api.hirenewtalent.ai/v1/engagements/eng_123/pass \-H "Authorization: Bearer hnt_test_YOUR_API_KEY"

    Example output

    json
    {"data": {"id": "eng_123","status": "passed","next_action": "engagement_closed","valid_actions": [],"message": "Candidate passed."}}
    POST

    /v1/engagements/:id/live-interview

    Request a live interview before making a final decision.

    engagements

    Example query

    bash
    curl -X POST https://api.hirenewtalent.ai/v1/engagements/eng_123/live-interview \-H "Authorization: Bearer hnt_test_YOUR_API_KEY"

    Example output

    json
    {"data": {"id": "eng_123","status": "live_interview_requested","next_action": "wait_for_live_interview","valid_actions": [],"message": "Live interview requested."}}
    POST

    /v1/engagements/:id/replacement

    Request a replacement for an active engagement.

    engagements

    Example query

    bash
    curl -X POST https://api.hirenewtalent.ai/v1/engagements/eng_123/replacement \-H "Authorization: Bearer hnt_test_YOUR_API_KEY" \-H "Content-Type: application/json" \-d '{"reason": "Timezone mismatch"}'

    Example output

    json
    {"data": {"id": "eng_123","status": "active","replacement_requested": true,"message": "Replacement requested."}}
    POST

    /v1/engagements/:id/terminate

    Terminate an active engagement. Requires a reason.

    engagements

    Example query

    bash
    curl -X POST https://api.hirenewtalent.ai/v1/engagements/eng_123/terminate \-H "Authorization: Bearer hnt_test_YOUR_API_KEY" \-H "Content-Type: application/json" \-d '{"reason": "Role no longer needed"}'

    Example output

    json
    {"data": {"id": "eng_123","status": "terminated","next_action": "engagement_ended","valid_actions": [],"message": "Engagement terminated."}}

    Messaging

    Embed client-to-talent communication inside your own application.

    GET

    /v1/conversations

    List conversations for the authenticated client.

    messages

    Example query

    bash
    curl "https://api.hirenewtalent.ai/v1/conversations?limit=20&offset=0" \-H "Authorization: Bearer hnt_test_YOUR_API_KEY"

    Example output

    json
    {"data": {"conversations": [{"id": "conv_123","participant_2_id": "tal_123","last_message_preview": "Thanks, I can start Monday.","last_message_at": "2026-04-13T12:00:00.000Z"}],"limit": 20,"offset": 0}}
    POST

    /v1/conversations

    Get or create a conversation with a talent profile.

    messages

    Example query

    bash
    curl -X POST https://api.hirenewtalent.ai/v1/conversations \-H "Authorization: Bearer hnt_test_YOUR_API_KEY" \-H "Content-Type: application/json" \-d '{"talent_profile_id": "tal_123"}'

    Example output

    json
    {"data": {"id": "conv_123","participant_1_id": "client_123","participant_2_id": "tal_123","created_at": "2026-04-13T12:00:00.000Z"}}
    GET

    /v1/conversations/:id/messages

    Fetch paginated messages in a conversation.

    messages

    Example query

    bash
    curl "https://api.hirenewtalent.ai/v1/conversations/conv_123/messages?limit=25&offset=0" \-H "Authorization: Bearer hnt_test_YOUR_API_KEY"

    Example output

    json
    {"data": {"messages": [{"id": "msg_123","conversation_id": "conv_123","sender_type": "human","content": "Can you start next Monday?","is_read": true,"created_at": "2026-04-13T12:00:00.000Z"}],"limit": 25,"offset": 0}}
    POST

    /v1/conversations/:id/messages

    Send a message to a conversation.

    messages

    Example query

    bash
    curl -X POST https://api.hirenewtalent.ai/v1/conversations/conv_123/messages \-H "Authorization: Bearer hnt_test_YOUR_API_KEY" \-H "Content-Type: application/json" \-d '{"content": "Can you start next Monday?"}'

    Example output

    json
    {"data": {"id": "msg_123","conversation_id": "conv_123","sender_type": "human","content": "Can you start next Monday?","created_at": "2026-04-13T12:00:00.000Z"}}

    Events

    Catch up on asynchronous engagement changes with one pull-based feed across the authenticated client's engagements.

    GET

    /v1/events

    Paginated event feed with opaque since cursor, limit clamped to 1-100, and at-least-once delivery semantics.

    engagements

    Example query

    bash
    curl "https://api.hirenewtalent.ai/v1/events?limit=50&since=opaque_cursor_123" \-H "Authorization: Bearer hnt_test_YOUR_API_KEY"

    Example output

    json
    {"data": {"events": [{"id": "evt_123","event_type": "engagement.status_changed","payload": {"engagement_id": "eng_123","previous_status": "invited","new_status": "pending_decision","next_action": "review_score_then_offer_or_pass"},"environment": "test","schema_version": 1,"created_at": "2026-04-13T12:00:00.000Z"}],"next_cursor": "opaque_cursor_456","has_more": false}}

    Request fields at a glance

    These are the fields most integrations send directly. Response-only fields and lifecycle-specific objects are covered in the data definitions above.

    Search body

    FieldTypeNotes
    querystringRequired. Natural-language role, skills, and experience description. Maximum 500 characters.
    deviceIdstringOptional. Client device identifier used by the search flow.
    hours_per_periodnumberOptional. Billing hours used when returning estimated_monthly_cost. Defaults to 80, or 40 for rolling_biweekly.
    billing_typestringOptional. monthly_recurring, rolling_4_week, or rolling_biweekly. Defaults to monthly_recurring.
    country_regionstringOptional pricing context: philippines, india, latin_america, or default.

    Pricing estimate query

    FieldTypeNotes
    role_titlestringRequired. Free-text role title. Maximum 120 characters. Unknown titles fall back to a general VA estimate.
    hours_per_periodnumberRequired. 80 or 160 for monthly/4-week billing; 40 or 80 for biweekly billing.
    billing_typestringRequired. monthly_recurring, rolling_4_week, or rolling_biweekly.
    country_regionstringOptional. philippines, india, latin_america, or default.

    Create engagement body

    FieldTypeNotes
    talent_profile_idstringRequired. The talent_id returned by search.
    role_titlestringRequired. Role being hired for. Maximum 120 characters.
    job_descriptionstringOptional. Job details used by pricing complexity classification and interview context. Maximum 5,000 characters.
    hours_per_periodnumberOptional. Billing hours for the engine-stamped quote.
    billing_typestringOptional. Billing cadence for the engagement.
    interview_modestringOptional. request_new sends a fresh interview; use_prior_score decides on a prior score when available.
    prior_invite_idstringOptional with use_prior_score. Selects a specific completed prior interview.

    Lifecycle action fields

    FieldTypeNotes
    reasonstringRequired for terminate; optional for replacement. Maximum 2,000 characters when provided.
    start_dateISO dateOptional PATCH field for expected engagement start date.

    Interview history query

    FieldTypeNotes
    role_titlestringOptional. Exact, case-insensitive role-title filter.
    sinceISO datetimeOptional. Return only interviews completed after this timestamp.
    limitnumberOptional. Defaults to 20; maximum 100.

    Interview generation body

    FieldTypeNotes
    role_titlestringRequired. Free-text role title for the generated interview.
    senioritystringOptional. Free-text seniority hint.
    responsibilitiesstringOptional. Responsibilities the interview should evaluate.
    must_have_skillsstring[]Optional. Skills or requirements that should appear in the rubric.
    interview_goalsstringOptional. Assessment priorities for the generated interview.
    persistbooleanOptional. Defaults to false. false previews/tests the output without saving; true saves the generated role configuration for later engagements.

    Messaging fields

    FieldTypeNotes
    contentstringRequired. Message body. Empty content is rejected. Maximum 5,000 characters.
    limitnumberOptional for message list requests. Defaults to 50. Valid range: 1-100.
    offsetnumberOptional for message list requests. Defaults to 0. Valid range: 0-10,000.

    Pricing guide

    Quote before you commit

    The role-level estimate endpoint lets you preview costs before picking a talent. The exact talent-specific offer rate is engine-controlled and locked at invite time; callers cannot override it in request bodies. Pricing reflects your submitted hours and billing type exactly.

    After POST /v1/engagements sends the interview invite, query GET /v1/engagements/:id and read engagement_pricing.client_rate for the locked client-facing rate.

    Role range estimate

    Returns entry_standard and senior_expert quotes for any role title — no specific talent required. Unknown titles fall back to general_va. The role_family field in the response shows which band was resolved.

    bash
    curl "$HNT_URL/v1/pricing/estimate?\role_title=Bookkeeper+for+SaaS+startup&\hours_per_period=80&\billing_type=monthly_recurring" \-H "Authorization: Bearer $HNT_KEY"
    json
    {"data": {"role_family": "bookkeeping_accounting","country": "philippines","billing_type": "monthly_recurring","hours_per_period": 80,"entry_standard": {"talent_wage_rate": 5.50,"client_rate": 8.25,"client_period_cost": 660.00},"senior_expert": {"talent_wage_rate": 9.00,"client_rate": 13.50,"client_period_cost": 1080.00}}}

    Pricing is engine-controlled

    The API does not accept caller-supplied rates or caller-supplied billing terms on rate-locked operations. These fields are silently ignored regardless of what you send:

    • talent_wage_rate on POST /v1/engagements — the engine computes the talent rate at invite time. Response carries X-Ignored-Fields: talent_wage_rate.
    • client_rate, hours_per_period, and billing_type on POST /v1/engagements/:id/offer — the API uses the saved engine-stamped quote and billing cadence from invite time. Response carries X-Ignored-Fields: client_rate, hours_per_period, billing_type.

    Use GET /v1/pricing/estimate for a pre-commitment role-level range. POST /v1/engagements locks the engine-controlled offer rate for the engagement flow, but caller-supplied rate fields are never used.

    Search examples

    Find and inspect talent

    Search accepts plain-language role descriptions. The optional pricing decoration may be omitted when pricing is unavailable.

    bash
    curl -X POST https://api.hirenewtalent.ai/v1/search \-H "Authorization: Bearer hnt_test_YOUR_API_KEY" \-H "Content-Type: application/json" \-d '{"query": "bookkeeper with QuickBooks Online and accounts receivable experience"}'
    json
    {"data": {"top": [{"talent_id": "talent_123","full_name": "Jane Doe","title": "Bookkeeper","match_score": 0.92,"bio": "Experienced in QuickBooks cleanup and monthly close.","skills": ["QuickBooks", "Accounts Receivable", "Reconciliation"]}],"query": "bookkeeper with QuickBooks Online and accounts receivable experience","total_matched": 42}}
    bash
    curl https://api.hirenewtalent.ai/v1/talent/talent_123 \-H "Authorization: Bearer hnt_test_YOUR_API_KEY"
    json
    {"data": {"id": "talent_123","full_name": "Jane Doe","avatar_url": "https://example.com/avatar.jpg","location": "Philippines","talent_profiles": {"title": "Bookkeeper","skills": ["QuickBooks", "Xero", "Payroll"],"experience_years": 6,"availability": "available","rating": 4.8},"talent_experiences": [{"title": "Accounting Assistant","company": "Remote Services Co.","description": "Handled reconciliations, AR, AP, and reporting."}]}}

    Engagement examples

    Start and manage hiring workflows

    Create an engagement to start the interview workflow. Then poll the engagement until it reaches the decision stage and follow the returned valid actions.

    bash
    curl -X POST https://api.hirenewtalent.ai/v1/engagements \-H "Authorization: Bearer hnt_test_YOUR_API_KEY" \-H "Content-Type: application/json" \-d '{"talent_profile_id": "talent_123","role_title": "Bookkeeper / Accountant","job_description": "Manage QuickBooks, reconciliations, AR follow-up, and monthly reporting.","hours_per_period": 80,"billing_type": "monthly_recurring"}'
    json
    {"data": {"engagement_id": "eng_123","invite_id": "invite_123","status": "invited","environment": "test","interview_mode": "request_new","own_interview": {"invite_id": "invite_123","status": "pending","score": null,"english_fluency": null},"prior_interviews": [],"next_action": "wait_for_interview_completion","valid_actions": []}}
    bash
    curl https://api.hirenewtalent.ai/v1/engagements/eng_123 \-H "Authorization: Bearer hnt_test_YOUR_API_KEY"
    json
    {"data": {"engagement_id": "eng_123","status": "pending_decision","invite_status": "completed","engagement_pricing": {"client_rate": 8.25,"client_period_cost": 660.00,"billing_type": "monthly_recurring","hours_per_period": 80},"score": {"overall_score": 87,"strengths": ["Clear communication", "Strong bookkeeping experience"],"improvements": ["Would benefit from more ERP exposure"],"summary": "Strong fit for bookkeeping and AR support."},"english_fluency": "fluent","next_action": "review_score_then_offer_or_pass","valid_actions": ["offer", "pass", "live-interview"]}}

    Send an offer

    Most integrations send an offer from pending_decision. If a client requests a live interview first, HireNewTalent may later mark the engagement hired after the internal live-interview outcome is recorded. From either state, call POST /v1/engagements/:id/offer. Send an empty object; the API uses the saved engine-stamped quote and billing cadence from invite time.

    • Live keys trigger the live offer flow and move the engagement to offer_sent.
    • Test keys update status only and return test_mode: true.
    • Do not send rates. client_rate, hours_per_period, and billing_type are ignored if present.
    bash
    # Send an empty body; engine-stamped rate from invite time is used automatically.curl -X POST https://api.hirenewtalent.ai/v1/engagements/eng_123/offer \-H "Authorization: Bearer hnt_test_YOUR_API_KEY" \-H "Content-Type: application/json" \-d '{}'
    bash
    curl -X PATCH https://api.hirenewtalent.ai/v1/engagements/eng_123 \-H "Authorization: Bearer hnt_test_YOUR_API_KEY" \-H "Content-Type: application/json" \-d '{"start_date": "2026-05-01"}'

    Messaging examples

    Create conversations and send messages

    Conversations are scoped to the authenticated client. The create endpoint is get-or-create: if a conversation already exists, the response returns its conversation_id.

    bash
    curl -X POST https://api.hirenewtalent.ai/v1/conversations \-H "Authorization: Bearer hnt_test_YOUR_API_KEY" \-H "Content-Type: application/json" \-d '{"talent_id": "talent_123"}'
    bash
    curl -X POST https://api.hirenewtalent.ai/v1/conversations/convo_123/messages \-H "Authorization: Bearer hnt_test_YOUR_API_KEY" \-H "Content-Type: application/json" \-d '{"content": "Hi Jane, we reviewed your interview and would like to discuss the role."}'
    bash
    curl "https://api.hirenewtalent.ai/v1/conversations/convo_123/messages?limit=25&offset=0" \-H "Authorization: Bearer hnt_test_YOUR_API_KEY"
    json
    {"data": {"messages": [{"id": "msg_123","sender_id": "client_123","sender_type": "human","content": "Hi Jane, we reviewed your interview and would like to discuss the role.","is_read": false,"created_at": "2026-04-13T12:00:00.000Z"}],"limit": 25,"offset": 0}}

    Message validation

    Sending a message requires non-empty content. Messages that fail content moderation return 400 content_moderation.

    Lifecycle

    Use next_action and valid_actions

    Engagement responses tell your integration what to do next. Use these fields instead of hardcoding assumptions from status names.

    Statusnext_actionvalid_actions
    invitedwait_for_interview_completion[]
    pending_decisionreview_score_then_offer_or_pass["offer", "pass", "live-interview"]
    live_interview_requestedwait_for_live_interview[]
    hiredwait_for_offer_preparation["offer"]
    offer_sentwait_for_talent_response[]
    activeengagement_active["replacement", "terminate"]
    passedengagement_closed[]
    terminated or completedengagement_ended[]
    FromToEndpoint
    pending_decisionoffer_sentPOST /v1/engagements/:id/offer
    pending_decisionpassedPOST /v1/engagements/:id/pass
    pending_decisionlive_interview_requestedPOST /v1/engagements/:id/live-interview
    live_interview_requestedhiredInternal/admin live interview outcome
    live_interview_requestedpassedInternal/admin live interview outcome
    hiredoffer_sentPOST /v1/engagements/:id/offer
    activeterminatedPOST /v1/engagements/:id/terminate

    Retry-safe transitions

    The offer, pass, live-interview, and terminate transition endpoints return 200 when the engagement is already in the target state. Those retry responses include meta.idempotent: true, for example calling pass again after the engagement is already passed. POST /v1/engagements/:id/replacement is not a status transition and can create a new replacement request each time.

    Polling guidance

    • Use GET /v1/engagements/:id for one active workflow and GET /v1/events when tracking multiple workflows.
    • Store the latest next_cursor from the events feed and pass it back as since on the next request.
    • Back off when no changes are returned, and always rely on next_action plus valid_actions before showing user actions.
    bash
    curl -X POST https://api.hirenewtalent.ai/v1/engagements/eng_123/pass \-H "Authorization: Bearer hnt_test_YOUR_API_KEY"
    bash
    curl -X POST https://api.hirenewtalent.ai/v1/engagements/eng_123/live-interview \-H "Authorization: Bearer hnt_test_YOUR_API_KEY"
    bash
    curl -X POST https://api.hirenewtalent.ai/v1/engagements/eng_123/replacement \-H "Authorization: Bearer hnt_test_YOUR_API_KEY" \-H "Content-Type: application/json" \-d '{"reason": "Timezone mismatch"}'

    Events feed

    Poll /v1/events to catch up on asynchronous changes across all engagements. Delivery is at least once, so dedupe by event id and ignore event types your integration does not recognize.

    Example query

    bash
    curl "https://api.hirenewtalent.ai/v1/events?limit=50" \-H "Authorization: Bearer hnt_test_YOUR_API_KEY"

    Example output

    json
    {"data": {"events": [{"id": "evt_123","event_type": "engagement.status_changed","payload": {"engagement_id": "eng_123","previous_status": "invited","new_status": "pending_decision","next_action": "review_score_then_offer_or_pass"},"environment": "test","schema_version": 1,"created_at": "2026-04-13T12:00:00.000Z"}],"next_cursor": "opaque_cursor_123","has_more": false}}
    Event typeWhen it firesCommon fields
    engagement.createdA new engagement is created.payload.engagement_id, payload.interview_mode
    engagement.rate_lockedThe engine-stamped rate is locked for an offer.payload.engagement_id, payload.client_rate, payload.hours_per_period, payload.billing_type
    engagement.status_changedThe engagement changes lifecycle state.payload.engagement_id, payload.previous_status, payload.new_status, payload.next_action
    engagement.replacement_requestedA replacement is requested on an active engagement.payload.engagement_id, payload.reason

    Test mode

    Exercise workflows before going live

    API keys beginning with hnt_test_ let you validate the integration without live billing or notification behavior. Test-only endpoints require test keys and test engagements.

    AreaTest behavior
    Search and profile readsReturn real marketplace data.
    Engagement creationCreates a test engagement and does not contact talent.
    Offer and talent responseState changes can be exercised without live billing or notifications.
    MessagesMessages are stored for testing without live notification behavior.
    Test endpointUse
    POST /v1/engagements/:id/_test/complete-interviewSimulates interview completion and moves invited to pending_decision.
    POST /v1/engagements/:id/_test/accept-offerSimulates offer acceptance and moves offer_sent to active.
    POST /v1/engagements/:id/_test/decline-offerSimulates offer decline and moves offer_sent to passed.
    ErrorMeaning
    403 forbiddenA live key is used, or the engagement is not a test engagement.
    400 invalid_stateThe engagement is not in the state required for the simulated action.
    400 not_applicableThe simulated action does not apply to the engagement mode, such as completing an interview for use_prior_score.
    404 not_foundThe engagement does not exist or is not owned by the authenticated client.

    Rate limits

    Plan for retries and backoff

    Authenticated rate limits are applied per client account. Paid limits scale with active hires, and responses include standard rate-limit headers so your client can throttle before hitting a hard limit.

    TierRequests/minRequests/day
    Free601,000
    Paid300 + 30 per hire, capped at 1,50010,000 + 1,000 per hire, capped at 100,000
    Enterprise600 or custom50,000 or custom
    http
    RateLimit-Limit: 60RateLimit-Remaining: 58RateLimit-Reset: 1744545600 HTTP/1.1 429 Too Many RequestsRetry-After: 42

    Errors

    Handle errors by code

    Switch on the stable error code instead of parsing human-readable messages. Include request_id when contacting support.

    HTTPCodeMeaning
    400validation_errorMissing or invalid request field.
    400invalid_actionThe requested action name is unknown.
    400invalid_prior_inviteThe requested prior interview cannot be used for this talent.
    400invalid_state_transitionThe requested action is not valid for the engagement's current state.
    400invalid_stateThe resource exists, but the requested operation cannot be performed yet.
    400no_prior_interviewuse_prior_score was requested, but no completed prior interview is available.
    400not_applicableThe requested test-mode action does not apply to this engagement mode.
    400role_not_supportedThe role_title does not map to a supported interview template.
    400content_moderationMessage content was blocked.
    401unauthorizedMissing, invalid, expired, or revoked API key.
    403forbiddenThe API key does not have the required permission scope.
    404not_foundThe resource does not exist or is not owned by the authenticated client.
    409no_stamped_quoteThe engagement does not have the engine-stamped quote required to send an offer.
    429rate_limitedThe client account exceeded its per-minute or per-day request limit.
    500database_errorAn underlying data operation failed.
    4xx/500engagement_creation_failedThe engagement could not be created.
    4xx/500generation_failedCustom interview generation failed.
    500persist_failedCustom interview generation succeeded, but persistence failed.
    4xx/500offer_failedThe offer could not be sent.
    4xx/500pricing_failedThe pricing estimate could not be generated.
    4xx/500search_failedSearch could not be completed.
    500internal_errorAn unexpected API error occurred.
    503service_unavailableA required API service is unavailable.
    javascript
    const response = await fetch(url, {headers: { Authorization: `Bearer ${process.env.HNT_API_KEY}` },}); const body = await response.json(); if (!response.ok) {const { code, message, details } = body.error; if (code === "rate_limited") {const retryAfter = Number(response.headers.get("Retry-After") || "60");await sleep(retryAfter * 1000);return retryRequest();} if (code === "invalid_state_transition") {return handleValidActions(details.valid_actions);} throw new Error(`${code}: ${message}`);}

    Ready to build with the API?

    Create an API key from your client dashboard, keep it in your backend, and start with search plus engagement polling.

    Open dashboard