JobFrame · API

Map a roster to JobFrame in one call.

Resolve a messy title, compute the coordinate distance between two canonical profiles, or bulk-map a whole roster — three metered endpoints on one authenticated surface. Every payload shape and price on this page is read from the live route handlers, not hand-typed. Full recipe set (CSV quickstart, MCP variant, billing detail): docs/jobframe/API-ADOPTION-KIT.md. How the matching itself works: /jobframe/matching.

The three meters

MeterEndpointPriceFree
metered-resolveGET /api/v1/resolve$0.01 / resolve (1,000/mo free)1,000/mo per IP
metered-matchGET /api/v1/match$0.05 / matchnone — key required
metered-bulk-mapPOST /api/v1/bulk-map$0.02 / employee-rownone — key required

The Developer plan is $99.00/mo with 25,000 included calls — only resolve draws down that allowance; match and bulk-map meter from call/row 1 regardless of plan. It's the only way to get a key today — buy it via Stripe Checkout, which mints your pa_… key on completion.

Auth & host

Send Authorization: Bearer pa_<your-key>. No key → free tier (resolve only, up to the ceiling above); an unkeyed match or bulk-map call returns 402 with a Stripe Checkout link so an agent can buy inline. Call the toolbox's own production host — not jobframe.global (its proxy rewrite only touches page routes; /api/* is excluded from that matcher on purpose):

export TOOLBOX_BASE_URL=https://people-analytics-toolbox.vercel.app
export PA_API_KEY=pa_...

Resolve one title

Free ≤ 1,000/mo per IP unkeyed, then $0.01 / resolve (1,000/mo free). Deterministic alias/fuzzy match against the JobFrame canon — no LLM in the serving path.

curl -sS "$TOOLBOX_BASE_URL/api/v1/resolve?title=Senior%20Software%20Engineer" \
  -H "Authorization: Bearer $PA_API_KEY"
{
  "contract": "pa-api/v1",
  "entitlement": { "plan": "developer", "keyPrefix": "pa_AbCdEfGh1234" },
  "usage": { "units": 1, "unit": "call", "billedCents": 1 },
  "data": {
    "normalizedTitle": "senior software engineer",
    "recommendedAction": "auto_accept",
    "candidates": [
      { "profileKey": "SWE.GEN.P5", "rank": 1, "confidence": 0.94,
        "confidenceBand": "high", "basis": "alias_match", "requiresReview": false }
    ],
    "explainer": "/jobframe/matching"
  }
}

Distance between two profiles

Keyed only ($0.05 / match). Pairwise (a+b) or nearest-neighbors (profileKey), over structural | content | pay | semantic coordinate editions.

curl -sS "$TOOLBOX_BASE_URL/api/v1/match?a=SWE.GEN.P5&b=SWE.GEN.P6&space=structural" \
  -H "Authorization: Bearer $PA_API_KEY"
{
  "contract": "pa-api/v1",
  "usage": { "units": 1, "unit": "call", "billedCents": 5 },
  "data": {
    "a": "SWE.GEN.P5", "b": "SWE.GEN.P6", "space": "structural",
    "edition": "2026-06.structural.1", "distance": 0.083, "band": "confident",
    "explainer": "/jobframe/matching"
  }
}

Map your roster in one call

Keyed only ($0.02 / employee-row), up to 5,000 rows per call. Distinct titles resolve once and share the result across matching rows; every row carries the honest 3-state action.

curl -sS -X POST "$TOOLBOX_BASE_URL/api/v1/bulk-map" \
  -H "Authorization: Bearer $PA_API_KEY" \
  -H "content-type: application/json" \
  -d '{
    "rows": [
      { "ref": "emp-001", "title": "Senior Software Engineer" },
      { "ref": "emp-002", "title": "Sr. SWE II" }
    ]
  }'
{
  "contract": "pa-api/v1",
  "usage": { "units": 2, "unit": "row", "billedCents": 4 },
  "data": {
    "summary": { "total": 2, "autoAccept": 2, "needsReview": 0, "insufficientEvidence": 0 },
    "rows": [
      { "ref": "emp-001", "title": "Senior Software Engineer", "action": "auto_accept",
        "profileKey": "SWE.GEN.P5", "confidence": 0.94, "confidenceBand": "high", "alternatives": [] }
    ],
    "explainer": "/jobframe/matching"
  }
}

CSV in? Transform the title column to rows: [{ ref, title }] first — the full quickstart (shell one-liner included) is in the API Adoption Kit linked above.

MCP variant (portfolio consumers)

The same capability is also reachable over MCP for AI-native consumers — a separate transport and auth system from the pa_… key above. MCP keys are operator-provisioned per consumer, not sold; there's no bridge from a Developer-plan purchase to MCP access today. Tool names: job-family-agent.resolve-title, job-family-agent.match, job-family-agent.coordinates.neighbors — there is no bulk-map tool over MCP; a roster means one call per row.

curl -sS -N -X POST "$TOOLBOX_BASE_URL/api/mcp" \
  -H "Authorization: Bearer $TOOLBOX_MCP_KEY" \
  -H "content-type: application/json" \
  -H "accept: application/json, text/event-stream" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "tools/call",
    "params": {
      "name": "job-family-agent.resolve-title",
      "arguments": { "title": "Senior Software Engineer" }
    }
  }'