DEV Community

Cover image for How I Gave an AI Agent Access to 20 Job APIs Through One Endpoint
whiteknightonhorse
whiteknightonhorse

Posted on

How I Gave an AI Agent Access to 20 Job APIs Through One Endpoint

The Problem: Job Data is Scattered Everywhere

If you've ever tried to build anything that touches job market data, you know the pain. Every job board has its own API, its own auth, its own rate limits, its own response format.

Want global coverage? You need Adzuna for 16 countries, Reed for UK, Arbeitnow for EU, Remotive for remote roles, TheirStack for tech stack analysis, Jooble for aggregated results, and probably five more I'm forgetting.

That's 7 API keys, 7 auth schemes (Basic Auth, Bearer tokens, keys-in-URL-path, no auth at all), 7 different response formats, and 7 sets of rate limit rules. For a single query like "find me Python developer jobs in Europe, preferably remote."

I spent the last week wiring all of these into a single MCP endpoint. Here's exactly how it works and how you can use it.

What MCP Changes About Multi-API Orchestration

Model Context Protocol (MCP) is the standard that lets AI agents discover and call tools dynamically. Instead of hardcoding API calls, your agent connects to an MCP server and gets a catalog of available tools — with typed schemas, descriptions, and pricing.

The key insight: the agent decides which tools to call based on the user's question. You don't write if/else logic for "if the user asks about UK jobs, call Reed; if they ask about remote, call Remotive." The LLM reads the tool descriptions and routes naturally.

Here's what 20 job-related tools look like through one MCP connection:

# Connect and discover job tools
curl -X POST https://apibase.pro/mcp \
  -H "Content-Type: application/json" \
  -d '{
    "jsonrpc": "2.0",
    "id": 1,
    "method": "prompts/get",
    "params": {
      "name": "discover_tools",
      "arguments": { "category": "jobs" }
    }
  }'
Enter fullscreen mode Exit fullscreen mode

The response lists every job tool with its parameters:

Tool What It Does Coverage
adzuna.search Job search with salary data 16 countries
adzuna.salary Salary histograms by role 16 countries
adzuna.categories Job category taxonomy Per-country
theirstack.jobs Tech stack-filtered job search Global, 181M+ postings
theirstack.companies Find companies by technology Global
jooble.search Aggregated search, 70+ countries Global
reed.search UK jobs with salary (GBP) UK
reed.details Full job details by ID UK
arbeitnow.jobs EU job listings DE, AT, CH, NL
remotive.search Remote-only curated listings Global remote
jobs.salary_data BLS salary statistics US
jobs.occupation_search O*NET occupation database US
jobs.esco_search EU skills/occupation taxonomy EU
jobs.job_search CareerJet search Global

That's one connection, one auth token, one response format. The agent picks which tool fits the question.

Building the Agent: From Question to Multi-Source Results

Let me walk through what happens when a user asks: "Find me senior Python developer jobs in Berlin, preferably remote, and compare salaries with London."

A well-prompted agent would break this into 3-4 tool calls:

Call 1: TheirStack for tech-stack-specific results

curl -X POST https://apibase.pro/api/v1/tools/theirstack.jobs/call \
  -H "Authorization: Bearer ak_live_..." \
  -H "X-PAYMENT: ..." \
  -H "Content-Type: application/json" \
  -d '{
    "keywords": "senior python developer",
    "country": "DE",
    "remote": true,
    "technologies": "python, django, fastapi",
    "limit": 10
  }'
Enter fullscreen mode Exit fullscreen mode

Response:

{
  "jobs": [
    {
      "title": "Senior Python Developer",
      "company": "Delivery Hero",
      "location": "Berlin",
      "country": "DE",
      "remote": true,
      "salary_min_usd": 75000,
      "salary_max_usd": 95000,
      "posted": "2026-03-28",
      "url": "https://..."
    }
  ],
  "count": 10
}
Enter fullscreen mode Exit fullscreen mode

Call 2: Reed for UK salary comparison

curl -X POST https://apibase.pro/api/v1/tools/reed.search/call \
  -H "Authorization: Bearer ak_live_..." \
  -H "X-PAYMENT: ..." \
  -d '{
    "keywords": "senior python developer",
    "location": "London",
    "salary_min": 60000,
    "permanent": true,
    "limit": 10
  }'
Enter fullscreen mode Exit fullscreen mode
{
  "jobs": [
    {
      "id": 56671234,
      "title": "Senior Python Developer",
      "company": "Revolut",
      "location": "London",
      "salary_min": 80000,
      "salary_max": 110000,
      "currency": "GBP",
      "applications": 47,
      "url": "https://www.reed.co.uk/jobs/..."
    }
  ],
  "total": 443,
  "count": 10
}
Enter fullscreen mode Exit fullscreen mode

Call 3: Remotive for remote-only options

curl -X POST https://apibase.pro/api/v1/tools/remotive.search/call \
  -H "Authorization: Bearer ak_live_..." \
  -H "X-PAYMENT: ..." \
  -d '{
    "search": "python senior",
    "category": "software-dev",
    "limit": 10
  }'
Enter fullscreen mode Exit fullscreen mode
{
  "jobs": [
    {
      "id": 982341,
      "title": "Senior Python Backend Engineer",
      "company": "GitLab",
      "category": "Software Development",
      "salary": "$130,000 - $170,000",
      "location_requirement": "Americas, EMEA",
      "tags": ["python", "django", "postgresql"],
      "url": "https://remotive.com/remote-jobs/..."
    }
  ],
  "count": 10,
  "total": 2847
}
Enter fullscreen mode Exit fullscreen mode

Call 4: Adzuna salary histogram

curl -X POST https://apibase.pro/api/v1/tools/adzuna.salary/call \
  -H "Authorization: Bearer ak_live_..." \
  -H "X-PAYMENT: ..." \
  -d '{
    "what": "python developer",
    "where": "london",
    "country": "gb"
  }'
Enter fullscreen mode Exit fullscreen mode

The agent now has: Berlin jobs with tech stack filters, London jobs with GBP salaries, global remote positions with USD salary ranges, and a salary distribution histogram. Total cost: 4 API calls × $0.001-0.002 each = less than $0.01 for a comprehensive multi-market job analysis.

The Part Nobody Talks About: Why 7 Providers, Not 1

Here's what I learned integrating all these job APIs in one day.

No single provider covers everything:

Need Best Provider Why
"Show me Python jobs" TheirStack Only one with tech stack filter (technologies_or)
"UK jobs with salary" Reed Structured min/max GBP salary, not free text
"Remote jobs only" Remotive Curated remote-only board, salary strings included
"Jobs in Germany" Arbeitnow EU-native, German market coverage
"Salary comparison" Adzuna Statistical salary histograms, not just listings
"Global search" Jooble 70+ countries, widest aggregation
"How competitive is this role?" Reed applications count per listing

The auth diversity is wild. In one afternoon I dealt with:

  • Bearer JWT tokens (TheirStack)
  • API key in URL path — literally /api/{key} (Jooble)
  • HTTP Basic Auth with key as username, empty password (Reed)
  • No auth at all (Arbeitnow, Remotive)
  • App ID + App Key as query params (Adzuna)

That's 5 different auth schemes for one category. An MCP gateway normalizes this — your agent sends one Authorization: Bearer header and the gateway handles the rest.

Response Format Normalization

This is the unsexy-but-critical part. Each API returns salary differently:

TheirStack:  "salary_min_usd": 75000, "salary_max_usd": 95000
Reed:        "minimumSalary": 80000.0, "maximumSalary": 110000.0, "currency": "GBP"
Remotive:    "salary": "$130,000 - $170,000"
Adzuna:      "salary_min": 45000, "salary_max": 65000 (no currency field, inferred from country)
Arbeitnow:   no salary field at all
Jooble:      "salary": "" (often empty)
Enter fullscreen mode Exit fullscreen mode

The adapter layer normalizes each response into a consistent shape. Reed's minimumSalary becomes salary_min. Remotive's free-text salary string gets passed through as-is (parsing "$130,000 - $170,000" into min/max is the agent's job — the API shouldn't guess).

Every adapter also strips HTML from descriptions (job boards love injecting &nbsp; and <b> tags into plain text fields) using a shared stripHtml() utility. This sounds trivial until you're debugging why an agent is hallucinating HTML entities.

Payment: Per-Call, Not Per-Month

Each job search costs $0.001 to $0.002 per call. The payment happens via x402 — the HTTP standard where:

  1. Agent calls a tool → gets 402 Payment Required with price
  2. Agent signs a USDC micropayment on Base
  3. Agent retries with payment proof in X-PAYMENT header
  4. Server verifies, escrows funds, calls the upstream API, returns data
  5. Escrow settles to the platform wallet

For a recruiting agent that runs 100 job searches per day across 7 providers, that's roughly $0.15/day. Compare that to subscribing to 7 different job APIs at $30-100/month each.

Traditional: 7 APIs × ~$50/month = $350/month
Per-call:    100 calls/day × $0.002 × 30 days = $6/month
Enter fullscreen mode Exit fullscreen mode

This is why per-call pricing matters for agents. Most agents are bursty — they run a batch of searches, synthesize results, then go idle. Paying subscriptions for idle capacity is exactly the wrong model.

Try It Yourself

The entire jobs toolkit is live right now. Connect any MCP client:

{
  "mcpServers": {
    "apibase": {
      "url": "https://apibase.pro/mcp",
      "transport": "streamable-http"
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Or use REST directly:

# Get all available job tools
curl -s https://apibase.pro/api/v1/tools | \
  python3 -c "
import sys,json
tools = json.load(sys.stdin)['data']
jobs = [t for t in tools if t['category'] == 'jobs' or 'job' in t['name'].lower()]
for t in jobs:
    print(f\"{t['id']:30s} \${t['pricing']['price_usd']}\")
"
Enter fullscreen mode Exit fullscreen mode

The MCP endpoint is at https://apibase.pro/mcp. The full tool catalog (409 tools across 30+ categories — not just jobs) is at https://apibase.pro/api/v1/tools. Source code is on GitHub.

The jobs category alone now has 20 tools across 7 specialized providers. Each one was chosen for a specific coverage gap — there's no overlap where one provider does everything another does. That's the point of a gateway: you pick the best tool for each question, not the best "one API to rule them all."


Built with APIbase.pro — 409 tools, 121 providers, one MCP endpoint.

Top comments (0)