Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.instaview.sk/llms.txt

Use this file to discover all available pages before exploring further.

Overview

The Sourcing API exposes InstaView’s AI-driven candidate sourcing pipeline as a fully programmable, asynchronous REST interface. You can initiate sourcing runs, refine criteria mid-session, enrich shortlisted profiles for contact discovery, and embed beautifully styled candidate cards directly into your ATS or internal dashboards. All sourcing operations are asynchronous — requests return immediately with a requestId, and results are delivered either via webhooks or polled through a results endpoint.

Asynchronous Request-Response Pattern

Required Scopes

OperationRequired Scope
Initiate sourcing runsourcing:write
Patch / re-run sourcing sessionsourcing:write
Get sourcing resultssourcing:read
Initiate enrichment runenrich:write
Get enrichment resultsenrich:write
Render HTML candidate cardsenrich:write

Execution Pipeline

When a sourcing run is initiated, the sourcing agent executes a fully automated pipeline — no clarifying questions, no interactive steps:
1

ICP Generation

The agent derives a complete Ideal Candidate Profile (ICP) from your title, jobDescription, location, and optional query. Skill expansion, title synonyms, location variants, and negative keywords are all populated automatically.
2

Query Compilation

A tailored search query is compiled against InstaView’s sourcing index. Skill expansions and localized terms maximize recall.
3

Candidate Search

The search is executed against external platform indices. A strict 15-second timeout with 2 automatic retries applies — if the external index is unavailable, a circuit-breaker failover triggers immediately and a sourcing.failed webhook is dispatched.
4

Enrichment & Matching

Profiles are enriched sequentially. Failed individual profiles are isolated and marked unbilled — the batch continues with the remaining candidates.
5

Webhook / Polling Delivery

The completed, ranked candidate list is delivered to your webhook endpoint or made available via GET /sourcing/{id}/results.

Initiating a Sourcing Run

curl -X POST https://api.instaview.sk/sourcing \
  -H "Authorization: Bearer sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "title": "Senior Staff ML Engineer",
    "jobDescription": "We are seeking a Staff ML Engineer to design and scale our agentic coding infrastructure...",
    "location": "Remote, USA",
    "query": "Prioritize candidates with active contributions to LangChain or vLLM.",
    "limit": 15,
    "webhookId": "3f9a12c7-44b8-4d32-b71f-e29a7d1e0f5c"
  }'

Response (202 Accepted)

{
  "success": true,
  "requestId": "req_9f3b827e-8c31-4bda-a7a2-b2d99d14f4e2",
  "status": "processing",
  "message": "Sourcing run accepted and queued for processing.",
  "webhookId": "3f9a12c7-44b8-4d32-b71f-e29a7d1e0f5c",
  "createdAt": "2026-05-20T13:20:45.000Z"
}

Polling for Results

If you do not use webhooks, poll GET /sourcing/{requestId}/results until status transitions from "processing" to "completed" or "failed".
async function pollResults(requestId) {
  while (true) {
    const res = await fetch(`https://api.instaview.sk/sourcing/${requestId}/results`, {
      headers: { 'Authorization': `Bearer ${process.env.INSTAVIEW_API_KEY}` },
    });

    const body = await res.json();

    if (body.status === 'completed') {
      return body.candidates;
    }

    if (body.status === 'failed') {
      throw new Error(body.errorMessage);
    }

    // Still processing — wait before polling again
    await new Promise(resolve => setTimeout(resolve, 5000));
  }
}
Avoid polling more frequently than once every 5 seconds. Excessive polling can trigger the GET /sourcing/*/results rate limit (120 requests/minute per API key).

Refining a Sourcing Session

After a run completes, use PATCH /sourcing/{requestId} to refine criteria or request additional candidates from the same session context. At least one of query or limit must be provided.
A PATCH request is only accepted after the current run transitions to "completed" or "failed". If a run is still "processing", the request returns 409 Conflict.
{
  "query": "Focus on startup founders with Kubernetes experience.",
  "limit": 5
}
The agent applies the updated query as a context patch and then evaluates limit additional profiles — all in a single asynchronous pass.

Enriching Candidates

Enrichment performs deep profile analysis including email discovery. It is fully asynchronous: submit profile IDs, receive a requestId, and poll GET /sourcing/enrich/{requestId}/results or await the enrich.completed webhook.
curl -X POST https://api.instaview.sk/sourcing/enrich \
  -H "Authorization: Bearer sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "profileIds": ["prof_a9238f82-a723", "prof_e8321c12-b912"],
    "webhookId": "3f9a12c7-44b8-4d32-b71f-e29a7d1e0f5c"
  }'

Response (202 Accepted)

{
  "success": true,
  "requestId": "enr_550e8400-e29b-41d4-a716-446655440001",
  "status": "processing",
  "message": "Enrichment run accepted and queued for processing.",
  "createdAt": "2026-05-20T13:21:00.000Z"
}
Each successfully enriched profile consumes 1 credit. Profiles that fail to enrich are not billed. For prepaid accounts, your balance must cover the full batch size upfront.

Enrichment Resilience

Individual profile failures within a batch are isolated: if one profile fails to enrich, the system marks it as failed, skips billing for it, and continues processing the rest of the batch.

Rendering HTML Candidate Cards

Generate self-contained, embeddable HTML profile cards for your ATS or dashboards. This endpoint is synchronous — it returns immediately with rendered cards.
curl -X POST https://api.instaview.sk/sourcing/render-html \
  -H "Authorization: Bearer sk_your_key_here" \
  -H "Content-Type: application/json" \
  -d '{
    "profileIds": ["prof_a9238f82-a723"],
    "theme": "dark"
  }'
Supported themes: "dark" (default) and "light".

Webhook Events

Configure a WebhookConfig and pass its id as webhookId when initiating runs. The webhook must subscribe to at least one of the relevant event types.

Sourcing Events

Registration Key (events[])Payload Label (event)Triggered When
"SOURCING_COMPLETED""sourcing.completed"Sourcing run finishes with scored candidates
"SOURCING_FAILED""sourcing.failed"Sourcing run encounters an unrecoverable error

Enrichment Events

Registration Key (events[])Payload Label (event)Triggered When
"ENRICH_COMPLETED""enrich.completed"Enrichment run completes (partial success is still completed)
"ENRICH_FAILED""enrich.failed"Enrichment run encounters an unrecoverable error
A webhook config that subscribes to a mix of event types (e.g. ["ANALYSIS_COMPLETED", "SOURCING_COMPLETED", "ENRICH_COMPLETED"]) is fully valid — all subscriptions are honored independently.

Billing & Credits

  • Sourcing: 1 credit per successfully sourced and matched candidate, billed based on the limit parameter.
  • Enrichment: 1 credit per successfully enriched profile (failed profiles are not billed).
  • Prepaid accounts: balance must cover the full limit before a run starts. Insufficient funds → 402 Payment Required.
  • Postpaid accounts: run immediately regardless of balance; invoiced at end of the billing cycle.

Multi-Tenant Security

All sourcing resources (requestIds, candidate lists, enrichment results) are strictly bound to the companyId associated with the authenticating API key:
  • An API key from Company A cannot access, patch, or enrich resources belonging to Company B.
  • Attempting to access another company’s requestId returns 404 REQUEST_NOT_FOUND — not 403 — to prevent resource enumeration.
  • A webhookId submitted with a sourcing run must belong to the same company as the API key; mismatched ownership returns 403 WEBHOOK_COMPANY_MISMATCH.

Rate Limits

EndpointRate Limit
POST /sourcing10 requests / minute
PATCH /sourcing/{id}30 requests / minute
GET /sourcing/{id}/results120 requests / minute
POST /sourcing/enrich50 requests / minute
GET /sourcing/enrich/{id}/results120 requests / minute
POST /sourcing/render-html50 requests / minute

Error Codes

HTTP StatusError CodeDescription
400INVALID_PAYLOADMissing required fields (title or jobDescription) or invalid syntax
400INVALID_PATCH_PAYLOADPATCH body omits both query and limit
401UNAUTHORIZEDAPI key is missing, expired, or deactivated
402INSUFFICIENT_FUNDSPrepaid account balance too low to cover the run’s limit
403INSUFFICIENT_SCOPESAPI key does not have the required scope
403WEBHOOK_COMPANY_MISMATCHProvided webhookId belongs to a different company
404REQUEST_NOT_FOUNDrequestId does not exist, has expired, or belongs to another company
404WEBHOOK_NOT_FOUNDProvided webhookId does not exist or is inaccessible
409RUN_IN_PROGRESSPATCH attempted while a run is still "processing"
422WEBHOOK_EVENT_NOT_SUBSCRIBEDWebhook config has no overlap with sourcing or enrichment event types
429RATE_LIMIT_EXCEEDEDRequest rate exceeded sliding window limits
503PROVIDER_TEMPORARILY_UNAVAILABLEExternal sourcing platforms experiencing outages