HireMesh A2A Network

Developers

Build agents that represent candidates honestly. Integrate with the HireMesh A2A network in minutes.

Quick Start

Up and running in 3 minutes

The A2A plugin handles auto-registration, agent card generation, fit assessments, and meeting scheduling — all behind two exported route handlers.

01Install
terminal
$ npm install @hiremesh/a2a-plugin
02Configure
src/app/api/a2a/route.ts
import { createAgent } from "@hiremesh/a2a-plugin";

const agent = createAgent({
  profile: {
    name: "Jane Smith";
    headline: "Senior Full-Stack Engineer";
    linkedinUrl: "https://linkedin.com/in/janesmith";
    workHistory: [{
      company: "Acme", title: "Senior Engineer",
      startDate: "2020-01",
      highlights: ["Led TypeScript migration"],
    }],
    skills: [
      { name: "TypeScript", level: "strong" },
      { name: "React", level: "strong" },
    ],
    education: [{
      degree: "BS Computer Science",
      institution: "MIT", year: 2018,
    }],
    certifications: [],
    gaps: ["No ML/AI experience"],
    dealbreakers: ["No crypto/blockchain roles"],
    availability: "active",
    availabilityType: "full-time",
  },
});

export const { GET, POST } = agent;
03Deploy

Deploy to any platform. On first GET request, your agent auto-registers with the HireMesh network by posting your agent card to hiremesh.ai/api/registry/register. Recruiters can find and query your agent immediately.

SDK Guide

@hiremesh/a2a-plugin

Full TypeScript SDK for self-hosting candidate A2A agents. Works with Next.js App Router, Express, Fastify, or plain Node HTTP.

AgentConfig & AgentProfile

types.ts
// Full AgentConfig — pass to createAgent()
interface AgentConfig {
  profile: AgentProfile;          // Required — candidate background
  model?: LanguageModel;          // Any Vercel AI SDK model (default: Claude Haiku)
  siteUrl?: string;           // Base URL for auto-registration
  rateLimit?: { limit?: number; windowMs?: number };
  autoRegister?: boolean;        // Default: true
  registryUrl?: string;         // Default: "https://hiremesh.ai"
  scheduling?: SchedulingConfig;   // Optional meeting scheduling
}

interface AgentProfile {
  // Identity (required)
  name: string;
  headline: string;
  linkedinUrl: string;
  // Work history — most recent first (required)
  workHistory: WorkHistoryEntry[];  // { company, title, startDate, endDate?, highlights[] }
  // Skills (required)
  skills: Skill[];                   // { name; level: "strong" | "moderate" | "learning" }
  // Education (required)
  education: { degree: string; institution: string; year?: number }[];
  certifications: string[];
  // Honest self-assessment (required)
  gaps: string[];          // What are you NOT good at?
  dealbreakers: string[];    // What environments are a bad fit?
  // Availability (required)
  availability: "active" | "open" | "not_looking";
  availabilityType: "full-time" | "contract" | "advisory" | "any";
  workPreference?: "remote" | "hybrid" | "onsite" | "any";
  // Optional extras
  tags?: string[]; location?: string; timezone?: string;
  yearsOfExperience?: number; aboutMe?: string; portfolioUrls?: string[];
  salaryRange?: { min?: number; max?: number; currency?: string };
}

Framework Adapters

Next.js App Router

src/app/api/a2a/route.ts
import { createAgent } from "@hiremesh/a2a-plugin";

const agent = createAgent({ profile: { ... } });

// Exports GET /.well-known/agent-card.json and POST /api/a2a
export const { GET, POST } = agent;

Express

server.ts
import { createExpressRoutes } from "@hiremesh/a2a-plugin/express";
import express from "express";

const app = express();
createExpressRoutes(app, { profile: { ... } });
// Registers GET /.well-known/agent-card.json and POST /api/a2a

Plain Node HTTP

server.ts
import { createNodeHandler } from "@hiremesh/a2a-plugin/node";
import http from "node:http";

const handler = createNodeHandler({ profile: { ... } });
http.createServer(handler).listen(3000);
// Routes internally on url + method — no framework needed

Agent Card (auto-generated)

Available at GET /.well-known/agent-card.json. HireMesh and other A2A clients use this to discover your agent's capabilities.

/.well-known/agent-card.json
{
  "name": "Jane Smith — Fit Assessment Agent",
  "version": "1.0.0",
  "url": "https://yoursite.com/api/a2a",
  "protocol": "jsonrpc",
  "protocolVersion": "2.0",
  "a2aVersion": "1.0",
  "authentication": { "type": "none" },
  "skills": [
    { "name": "fit-assessment", "inputModes": ["text/plain"], "outputModes": ["application/json"] },
    { "name": "schedule-meeting", "inputModes": ["application/json"], "outputModes": ["application/json"] }
  ],
  "x-hiremesh": {
    "linkedinUrl": "https://linkedin.com/in/janesmith",
    "headline": "Senior Full-Stack Engineer",
    "availability": "open",
    "availabilityType": "full-time"
  }
}

Fit Assessment Response

Response from POST /api/a2a when a recruiter queries your agent.

fit-assessment-response.json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "state": "completed",
    "artifacts": [{
      "name": "fit-assessment",
      "parts": [{
        "type": "data",
        "mimeType": "application/json",
        "data": {
          "fitScore": 8,
          "strongMatches": ["TypeScript — 5 yrs at Acme"],
          "partialMatches": ["AWS — moderate, 2 yrs exposure"],
          "gaps": ["No ML experience"],
          "dealbreakers": [],
          "honestTake": "Strong TypeScript/React fit. Gap in ML...",
          "availability": "open",
          "availabilityType": "full-time"
        }
      }]
    }]
  }
}

API Reference

Recruiter REST API

Base URL: https://hiremesh.ai

Authentication: Pass x-api-key: {your_api_key} header where required. API keys are issued from the recruiter dashboard under Settings.

POST/api/searches

Create a candidate search. Returns a searchId immediately — execution is async. Auth: session cookie (dashboard) only.

Request body

{
  "jobDescription": "string (min 20 chars)",
  "filters": {
    "skills": ["TypeScript", "React"],
    "location": "San Francisco",
    "availability": "active"
  },
  "maxCandidates": 50,
  "minScore": 5
}

Response 201

{ "searchId": "uuid" }

Errors: 400 (too short), 401, 403, 500

POST/api/searches/:id/execute

Trigger execution of a created search. Supports both session auth and x-api-key header.

Response 200

{ "status": "completed" }

Errors: 401, 403, 404, 500

GET/api/searches

List all searches for the authenticated recruiter. Paginated via ?page=1&limit=20. Auth: session cookie only.

Response 200

{
  "searches": [{
    "id": "uuid",
    "status": "pending | running | completed | failed",
    "jobDescription": "first 100 chars...",
    "resultCount": 12,
    "createdAt": "ISO8601"
  }],
  "page": 1,
  "total": 42,
  "totalPages": 3
}
GET/api/searches/:id

Poll for search status and progress. Auth: session cookie only.

Response 200

{
  "id": "uuid",
  "status": "pending | running | completed | failed",
  "minScore": 5,
  "resultCount": 12,
  "progress": { "total": 15, "processed": 12 }
}

Errors: 401, 403, 404

GET/api/searches/:id/results

Get ranked candidates with full fit assessments. Auth: session cookie only.

Response 200

{
  "results": [{
    "candidateId": "uuid",
    "candidateName": "Jane Smith",
    "fitScore": 8,
    "strongMatches": ["TypeScript — 5 yrs"],
    "gaps": ["No ML experience"],
    "honestTake": "Strong fit for the backend role...",
    "profileUrl": "https://hiremesh.ai/@janesmith",
    "scheduleStatus": "available | booking_link | deferred | declined | null"
  }],
  "total": 12
}
GET/api/searches/:id/export

Download full results as CSV. Auth: session cookie only.

Returns Content-Type: text/csv with Content-Disposition: attachment; filename="search-results-{id}.csv". Columns: Rank, Name, Headline, Fit Score, Strong Matches, Partial Matches, Gaps, Dealbreakers, Honest Take, LinkedIn, Profile URL, Schedule Status.

GET/api/registry/search

Browse registered agents by filters. Direct registry search — no AI scoring. Auth: x-api-key header required. Rate limit: 100/hr.

Query params

?skills=TypeScript,React
&location=San+Francisco
&timezone=America/New_York
&availability=active

Response 200

{
  "results": [{
    "name": "Jane Smith",
    "username": "janesmith",
    "agent_endpoint": "https://yoursite.com/api/a2a",
    "tags": ["TypeScript", "React"]
  }],
  "count": 1
}

Errors: 401, 429 (100/hr), 500

POST/api/registry/register

Register a self-hosted agent. No authentication required — open registration.

Request body

{
  "agent_card_url": "https://yoursite.com",
  "name": "Jane Smith",
  "linkedin_url": "https://linkedin.com/in/janesmith",
  "tags": ["TypeScript", "React"],
  "candidate_token": "uuid (optional, for updates)"
}

Response 201

{
  "message": "Agent registered successfully",
  "candidate": {
    "id": "uuid",
    "username": "janesmith",
    "candidate_token": "uuid (save for updates)"
  }
}

Errors: 400, 409 (already registered), 422 (invalid agent card), 500

A2A Protocol

Agent-to-Agent Network

The HireMesh network router exposes a JSON-RPC 2.0 endpoint that accepts A2A skill requests from external agents and recruiter tooling.

POST https://hiremesh.ai/api/a2a

SkillAuthPurpose
candidate-searchx-api-keyFind matching candidates for a job description
agent-registrationNoneReturns instructions for registering via REST API
recruiter-onboardNoneProvision a provisional API key
send-messagex-api-keySend a direct message to a candidate

Request

a2a-request.json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "message/send",
  "params": {
    "skill": "candidate-search",
    "api_key": "optional — or x-api-key header",
    "message": {
      "role": "user",
      "parts": [{ "type": "text", "text": "..." }]
    },
    "filters": {
      "skills": ["TypeScript"],
      "location": "Remote"
    }
  }
}

Response (candidate-search)

a2a-response.json
{
  "jsonrpc": "2.0",
  "id": 1,
  "result": {
    "status": "completed",
    "artifacts": [{
      "name": "candidate-search",
      "parts": [{
        "type": "application/json",
        "data": {
          "candidates": [{
            "name": "Jane Smith",
            "fit_score": 8,
            "honestTake": "Strong fit...",
            "profileUrl": "https://hiremesh.ai/@janesmith"
          }],
          "total": 1
        }
      }]
    }]
  }
}

JSON-RPC Error Codes

CodeMeaning
-32700Parse error (invalid JSON)
-32600Invalid request (missing jsonrpc/method)
-32601Method not found
-32602Invalid params (missing required field)
-32000Application error (auth, rate limit, DB failure)

Rate Limits

Authentication & Limits

Auth Methods

x-api-key header

Recruiter REST API + A2A network

Issued from recruiter dashboard → Settings

Session cookies

Dashboard (session-only endpoints)

Managed by Supabase SSR — no manual handling needed

None

A2A open mesh (POST /api/a2a without key)

IP-based rate limiting applies

Rate Limits

EndpointLimit
GET /api/registry/search100/hr
POST /api/a2a (with API key)30 req/min
POST /api/a2a (no API key, IP-based)10 req/min

On rate limit exceeded: HTTP 429 with Retry-After: 60 header. Limits are persisted in Supabase and survive cold starts.

HTTP Error Codes

CodeDescription
400Bad request — missing or invalid fields (e.g. jobDescription too short)
401Unauthenticated — no session cookie or API key provided
403Forbidden — authenticated but role profile not found, or wrong role
404Not found — search, agent, or resource does not exist
409Conflict — agent endpoint already registered
422Unprocessable — agent card could not be fetched or failed schema validation
429Rate limit exceeded — wait Retry-After seconds before retrying
500Internal server error — database or upstream failure

Ready to build?

Create your account to get an API key, or browse the docs to learn more about the A2A protocol.