Developer guide · Resume data API

Resume Parsing API Integration Guide

Automate candidate data extraction end-to-end: submit a PDF or DOCX, receive structured JSON, and stream matched candidates into your ATS. This guide walks through authentication, sync and async ingestion, response shape, webhooks, and rate limits for the Grophi resume data API.

1. Why a resume parsing API

Manual CV review scales linearly with headcount. A resume data API converts an unstructured PDF into a typed JSON object in under a second, so recruiters, ATS platforms, and staffing tools can index candidates the moment they arrive. Grophi's parser is multimodal — it reads native PDF text, OCR's scans, and interprets tables and columns without breaking layout heuristics.

2. Authentication

Every request carries a workspace API key in the Authorization header. Generate one under Settings → Developer, then treat it like any production secret — never embed it in a client bundle.

curl -H "Authorization: Bearer $GROPHI_API_KEY" \
     https://app.gogrophi.com/api/v1/whoami

3. Sync parsing: single CV

Send a multipart upload to /api/v1/source. The response contains the structured candidate object immediately — ideal for careers-page form submissions and Chrome extensions.

POST /api/v1/source
Authorization: Bearer $GROPHI_API_KEY
Content-Type: multipart/form-data

file=@/tmp/jane_doe.pdf
role_id=00000000-0000-0000-0000-000000000000  # optional

4. Async ingestion: bulk pipelines

For nightly imports or migration from a legacy ATS, POST batches to /api/v1/ingest with a callback URL. The endpoint enqueues each file, returns a job id, and calls your webhook once each candidate is parsed and deduped.

POST /api/v1/ingest
{
  "callback_url": "https://your-app.com/webhooks/grophi",
  "files": [
    { "url": "https://cdn.example.com/cvs/alice.pdf" },
    { "url": "https://cdn.example.com/cvs/bob.docx" }
  ]
}

5. Response schema

Grophi returns a stable, versioned JSON payload. Fields the parser cannot confidently determine come back as null rather than a guessed string — safer for downstream matching.

{
  "candidate_id": "cnd_01H...",
  "full_name": "Jane Doe",
  "emails": ["jane@example.com"],
  "phones": ["+1 415 555 0142"],
  "location": { "city": "San Francisco", "country": "US" },
  "current_title": "Senior Backend Engineer",
  "experience": [{
    "company": "Acme",
    "title": "Senior Backend Engineer",
    "start": "2023-01",
    "end": null,
    "responsibilities": ["Owned billing platform", "Led migration to Postgres 16"]
  }],
  "education": [{ "school": "UC Berkeley", "degree": "BS Computer Science", "end": "2018" }],
  "skills": ["Go", "PostgreSQL", "Kubernetes"],
  "years_experience": 7.2
}

6. Webhooks & retries

Every async callback is signed with HMAC-SHA256 over the raw body. Verify with the shared secret before trusting the payload. Failed deliveries are retried with exponential backoff for 24 hours.

import { createHmac, timingSafeEqual } from "crypto";

const expected = createHmac("sha256", process.env.GROPHI_WEBHOOK_SECRET!)
  .update(rawBody)
  .digest("hex");

if (!timingSafeEqual(Buffer.from(signature), Buffer.from(expected))) {
  return new Response("invalid signature", { status: 401 });
}

7. Rate limits & errors

  • Sync: 30 requests / minute / workspace.
  • Async batch: 5,000 CVs / hour on the Growth plan.
  • Max file size: 10 MB per resume.
  • Errors: standard 4xx/5xx codes with a { error, hint } body.

Ready to integrate?

Spin up a workspace, mint an API key, and parse your first resume in under 5 minutes.

Get an API key

Related reading: Private Talent Pool vs ATS.