API reference · v1 · GA

cvparser.io API

Drop in a CV in any format — get back clean structured JSON in <2 seconds. REST, JSON-only, bearer-token auth. Choose your AI provider (Claude, GPT-4, or local spaCy NER) at the workspace level.

Base URL: https://api.cvparser.io
Latest version: v1.0.0
Schema: @cvparser/types

Overview

cvparser converts CVs (PDF, DOCX, DOC, HTML, plain text) into a normalised candidate object validated by Zod. Every parse runs through the same extractor pipeline.

  • One synchronous endpoint. Most CVs respond inline in 1–2s.
  • Strict schema. Missing fields are null — we never hallucinate values.
  • Public demo. Try the API without auth via /demo/parse.

Authentication

All non-demo requests must include an Authorization header with a workspace bearer token. Tokens are managed in your Dashboard. Live keys start with cvp_live_; sandbox keys with cvp_test_.

Keep keys server-side
Don't ship live keys in browser bundles or mobile apps. Use a thin proxy on your backend. Rotate keys quarterly from the dashboard — old keys remain valid for 30 days.

Quickstart

Send your first parse with a single command. The response wraps the candidate object in { success, data }. Costs 1 credit on a 2xx response. To only extract the sections you need (and cut LLM cost), see Selecting sections below.

POST/parse
curl -X POST https://api.cvparser.io/parse \
  -H "Authorization: Bearer cvp_live_a8f...kT2" \
  -F "file=@./candidate.pdf"
Response
{
  "success": true,
  "data": {
    "fullName": "Sarah Chen",
    "headline": "Senior Frontend Engineer",
    "email": "sarah.chen@gmail.com",
    "phone": "+44 7700 900123",
    "location": "London, UK",
    "linkedin": "https://linkedin.com/in/sarahchen",
    "github": null,
    "website": null,
    "bio": "Frontend engineer with 8+ years...",
    "confidence": 0.994,
    "workHistory": { "confidence": 0.97, "items": [ ... ] },
    "education":   { "confidence": 0.99, "items": [ ... ] },
    "skills":      { "confidence": 0.96, "items": [ ... ] }
  }
}

Selecting sections

By default a parse returns every CV section. Pass `?sections=` (on /parse) or a JSON `sections: []` field (on /parse/text) to extract only what you need — the request builds a reduced JSON schema, trims the prompt, and costs proportionally less. The response still uses the same envelope; unrequested sections are simply omitted from `data`.

POST/parse?sections=…
Valid section keys
candidate · workHistory · education · skills · certifications · licences · projects · courses · languages · publications · patents · honorsAwards
  • Comma-separated on the REST query (?sections=workHistory,skills); a JSON array on /parse/text.
  • Omitted⇒ full extraction (every section). Pass nothing to keep today's behaviour.
  • Unknown keys 400. Validation happens before any LLM call, so you never pay for a typo.
  • Field-level narrowing within a list section (e.g. only the company + title of each work-history item) is GraphQL-only — see the GraphQL playground at /graphql.
curl -X POST "https://api.cvparser.io/parse?sections=workHistory,skills" \
  -H "Authorization: Bearer cvp_live_a8f...kT2" \
  -F "file=@./candidate.pdf"
Response
{
  "success": true,
  "data": {
    "workHistory": { "confidence": 0.97, "items": [ ... ] },
    "skills":      { "confidence": 0.96, "items": [ ... ] }
  }
}

Errors

cvparser uses conventional HTTP status codes. 2xx for success, 4xx for client errors (validation, auth, quota), 5xx for our problems. Errors always include a JSON envelope { success: false, error: string }.

200OKParse succeeded.
400invalid_fileFile missing, unreadable, or unsupported MIME.
401invalid_api_keyMissing / malformed / revoked bearer token.
402insufficient_creditsWorkspace is out of credits.
413file_too_largeAbove the 25 MB per-file cap.
422low_confidenceParsed, but overall confidence below the workspace threshold.
429rate_limitedSlow down — see Retry-After header.
500internal_errorOur side. Auto-retried 3× before surfacing.

Rate limits

Defaults are 60 parses / minute per workspace on Starter & Pro, 600 / min on Business, custom on Enterprise. The public demo endpoint is IP-rate-limited. We return X-RateLimit-Limit and X-RateLimit-Remaining headers on every response.

The Candidate object

Every parse returns a Candidate envelope validated by the @cvparser/types Zod schema. Below are the top-level keys. See the shared schema for the full nested shape.

Param
Type
Notes
fullNamerequired
string
Candidate's full name.
headlinerequired
string
Brief professional focus line.
emailrequired
string
Best-known email address.
phonerequired
string
Phone number, format preserved.
locationrequired
string
City / region / country.
biorequired
string
Top-of-CV personal statement.
linkedin
string | null
LinkedIn profile URL, or null.
github
string | null
GitHub profile URL, or null.
website
string | null
Personal site URL, or null.
workHistoryrequired
object
{ confidence, items[] } — roles with title, company, dates, description.
educationrequired
object
{ confidence, items[] } — institution, degree, field, dates.
skillsrequired
object
{ confidence, items[] } — { name, type: 'soft' | 'tech' }.
certificationsrequired
object
{ confidence, items[] }.
languagesrequired
object
{ confidence, items[] } — language + CEFR proficiency.
projectsrequired
object
{ confidence, items[] }.
publicationsrequired
object
{ confidence, items[] }.
patentsrequired
object
{ confidence, items[] }.
honorsAwardsrequired
object
{ confidence, items[] }.
coursesrequired
object
{ confidence, items[] }.
licencesrequired
object
{ confidence, items[] }.
confidencerequired
number
Overall extraction confidence 0–1.

Parse a CV (file upload)

Multipart upload. PDF, DOCX, DOC, HTML, plain text are all supported. Costs 1 credit per parse — charged only on a 2xx response.

POST/parse
Param
Type
Notes
filerequired
binary
Multipart file field. ≤ 25 MB.
sections
query (csv)
Optional. Comma-separated list of section keys to extract — see Selecting sections.
curl -X POST https://api.cvparser.io/parse \
  -H "Authorization: Bearer cvp_live_a8f...kT2" \
  -F "file=@./candidate.pdf"
Response
{
  "success": true,
  "data": {
    "fullName": "Sarah Chen",
    "headline": "Senior Frontend Engineer",
    "email": "sarah.chen@gmail.com",
    "phone": "+44 7700 900123",
    "location": "London, UK",
    "linkedin": "https://linkedin.com/in/sarahchen",
    "github": null,
    "website": null,
    "bio": "Frontend engineer with 8+ years...",
    "confidence": 0.994,
    "workHistory": { "confidence": 0.97, "items": [ ... ] },
    "education":   { "confidence": 0.99, "items": [ ... ] },
    "skills":      { "confidence": 0.96, "items": [ ... ] }
  }
}

Parse a CV (raw text)

Send pre-extracted CV text directly — skips file extraction. Useful when you already have the text from another source.

POST/parse/text
Param
Type
Notes
textrequired
string
Raw CV text. Minimum 30 characters.
sections
string[]
Optional JSON array of section keys to extract — see Selecting sections.
curl -X POST https://api.cvparser.io/parse/text \
  -H "Authorization: Bearer cvp_live_a8f...kT2" \
  -H "Content-Type: application/json" \
  -d '{ "text": "Sarah Chen\nSenior Frontend Engineer..." }'
Response
{
  "success": true,
  "data": {
    "fullName": "Sarah Chen",
    ...
  }
}

Public demo endpoint

Unauthenticated, IP-rate-limited demo endpoint. Same response shape as /parse. Use it to wire up trial flows or evaluation harnesses without provisioning a key.

POST/demo/parse
Not for production
The demo endpoint is rate-limited per IP and may have looser SLAs. Move to the authenticated endpoint as soon as you have a key.
curl -X POST https://api.cvparser.io/demo/parse \
  -F "file=@./candidate.pdf"
Response
{
  "success": true,
  "data": { ... }
}

Libraries & SDKs

The API is plain REST — any HTTP client works. Below are the no-dependency choices for the popular languages.

Node.js
Node 18+
global fetch + FormData (built-in)
Python
3.8+
pip install requests
Go
stdlib
net/http + mime/multipart
REST
v1.0.0
curl, fetch, axios — anything