API Reference
parseResume(input, options)
The main function. Accepts a PDF buffer and returns structured resume data.
Parameters
input — Buffer | ArrayBuffer | Uint8Array
The PDF file content. All three buffer types are accepted.
options — ResumeIntelOptions
| Option | Type | Default | Description |
|---|---|---|---|
model |
LanguageModel |
required | Any Vercel AI SDK compatible model |
maxRetries |
number |
3 |
Max self-correction attempts per section on validation failure |
layoutStrategy |
'spatial' | 'linear' |
'spatial' |
PDF text extraction strategy |
useTaskDecomposition |
boolean |
true |
Run parallel per-section extractions |
sections |
ResumeSectionKey[] |
see below | Which sections to extract |
outputSchema |
ZodType |
JSON Resume v1 | Custom Zod schema to replace the default output schema |
systemPromptPrefix |
string |
'' |
Custom instructions injected before extraction prompts |
disableOcr |
boolean |
false |
Disable OCR fallback — required on Vercel/Lambda |
maxConcurrency |
number |
undefined |
Limit parallel section calls (useful for rate-limited APIs) |
onProgress |
(section, success) => void |
— | Called after each section extraction |
ocrLanguage |
string |
'eng' |
Tesseract language code for non-English CVs (e.g. 'fra', 'eng+fra') |
abortSignal |
AbortSignal |
— | Standard abort signal for cancellation |
redactPii |
boolean |
false |
Redact PII before LLM submission, reinject after extraction |
Default sections (when sections is not specified):
basics, work, education, skills, languages, projects, certificates, volunteer
All available sections:
basics, work, education, skills, languages, projects,
awards, certificates, publications, volunteer, interests, references
Return value
Promise<ResumeIntelResult>
interface ResumeIntelResult {
data: JsonResume // JSON Resume v1 compatible object (or custom outputSchema shape)
meta: ExtractionMeta
}
interface ExtractionMeta {
durationMs: number
retryCount: number
ocrFallback: boolean
layoutStrategy: 'spatial' | 'linear'
pageCount: number
sectionsRequested: string[]
tokenUsage?: {
promptTokens: number
completionTokens: number
totalTokens: number
}
sectionResults?: Array<{
section: string
success: boolean
retryCount: number
error: string | null
confidenceScore?: number // 0.0–1.0 — added in v0.2.1
}>
}PII Redaction
const result = await parseResume(buffer, {
model,
redactPii: true,
})
// The LLM never sees "john.doe@gmail.com" — it processes "__PII_EMAIL_0__"
// result.data.basics.email is still "john.doe@gmail.com"See the PII Redaction page for full documentation.
Confidence scores
const result = await parseResume(buffer, { model })
for (const s of result.meta.sectionResults ?? []) {
console.log(`${s.section}: ${s.confidenceScore}`)
// basics: 0.87 work: 1.00 skills: 1.00
}Selecting sections
// Extract only what you need — saves tokens and time
const result = await parseResume(buffer, {
model,
sections: ['basics', 'work', 'education'],
})
// Extract everything
import { ALL_SECTIONS } from '@edwinfom/resume-intel'
const result = await parseResume(buffer, {
model,
sections: [...ALL_SECTIONS],
})Custom output schema
import { z } from 'zod'
const result = await parseResume(buffer, {
model,
outputSchema: z.object({
fullName: z.string(),
contactEmail: z.string().email().optional(),
technicalSkills: z.array(z.string()),
}),
useTaskDecomposition: false,
})Rate limiting with maxConcurrency
// Limit to 3 concurrent section calls — avoids 429 on DeepSeek free tier
const result = await parseResume(buffer, {
model,
maxConcurrency: 3,
})Progress tracking with onProgress
const result = await parseResume(buffer, {
model,
onProgress: (section, success) => {
console.log(`${section}: ${success ? 'done' : 'failed'}`)
},
})Non-English CVs with ocrLanguage
// French CV scanned
const result = await parseResume(buffer, {
model,
ocrLanguage: 'fra',
})
// Mixed English + French
const result = await parseResume(buffer, {
model,
ocrLanguage: 'eng+fra',
})streamResume(input, options)
AsyncGenerator version of parseResume(). Yields events as each section is extracted.
import { streamResume } from '@edwinfom/resume-intel'
for await (const event of streamResume(buffer, { model })) {
if (event.type === 'section') updateUI(event.section, event.data)
if (event.type === 'error') console.warn(event.section, event.error)
if (event.type === 'done') setResult(event.result)
}Accepts the same options as parseResume(), including redactPii. See the Streaming page for full documentation.
redactPii / reinjectPii / describePiiRedaction
Utility functions for custom redaction pipelines.
import { redactPii, reinjectPii, describePiiRedaction } from '@edwinfom/resume-intel'
const { redactedText, placeholders } = redactPii(rawText)
console.log(describePiiRedaction({ redactedText, placeholders }))
// "2 emails, 3 urls, 1 phone"
const restored = reinjectPii(extractedData, placeholders)See the PII Redaction page for full documentation.
JsonResumeSchema
The Zod schema for the JSON Resume v1 specification.
import { JsonResumeSchema } from '@edwinfom/resume-intel'
const result = JsonResumeSchema.safeParse(myData)
if (!result.success) {
console.error(result.error.issues)
}SectionSchemas
Individual Zod schemas for each section.
import { SectionSchemas } from '@edwinfom/resume-intel'
const workResult = SectionSchemas.work.safeParse(myWorkData)Available keys: basics, work, education, skills, languages, projects, awards, certificates, publications, volunteer, interests, references
ALL_SECTIONS / DEFAULT_SECTIONS
import { ALL_SECTIONS, DEFAULT_SECTIONS } from '@edwinfom/resume-intel'
console.log(ALL_SECTIONS)
// ['basics', 'work', 'education', 'skills', 'languages', 'projects',
// 'awards', 'certificates', 'publications', 'volunteer', 'interests', 'references']
console.log(DEFAULT_SECTIONS)
// ['basics', 'work', 'education', 'skills', 'languages', 'projects', 'certificates', 'volunteer']normalizeDate / cleanUrl
Utility functions exposed for advanced use cases.
import { normalizeDate, cleanUrl } from '@edwinfom/resume-intel'
normalizeDate('2024-01-01') // → '2024'
normalizeDate('2024-08-01') // → '2024-08'
normalizeDate('2024-08-15') // → '2024-08-15'
normalizeDate('Present') // → null (caller should omit the field)
cleanUrl('https://github.com/user') // → 'https://github.com/user'
cleanUrl('https://vibe-') // → null (truncated)
cleanUrl('') // → nullError classes
ResumeExtractionError
Thrown when the LLM fails to produce valid data after all retry attempts.
import { ResumeExtractionError } from '@edwinfom/resume-intel'
try {
const result = await parseResume(pdfBuffer, { model })
} catch (error) {
if (error instanceof ResumeExtractionError) {
console.error(error.message)
console.error(error.cause)
}
}OcrNotEnabledError
Thrown when a scanned PDF is detected but OCR is disabled or fails.
import { OcrNotEnabledError } from '@edwinfom/resume-intel'
try {
const result = await parseResume(pdfBuffer, { model })
} catch (error) {
if (error instanceof OcrNotEnabledError) {
console.error('OCR failed:', error.message)
}
}TypeScript types
import type {
ResumeIntelOptions,
ResumeIntelResult,
ExtractionMeta,
SectionExtractionResult,
TokenUsage,
JsonResume,
ResumeSectionKey,
StreamResumeEvent,
} from '@edwinfom/resume-intel'