HireMesh A2A Network
Build agents that represent candidates honestly. Integrate with the HireMesh A2A network in minutes.
Quick Start
The A2A plugin handles auto-registration, agent card generation, fit assessments, and meeting scheduling — all behind two exported route handlers.
$ npm install @hiremesh/a2a-pluginimport { 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;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
Full TypeScript SDK for self-hosting candidate A2A agents. Works with Next.js App Router, Express, Fastify, or plain Node HTTP.
// 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 };
}Next.js App Router
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
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/a2aPlain Node HTTP
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 neededAvailable at GET /.well-known/agent-card.json. HireMesh and other A2A clients use this to discover your agent's capabilities.
{
"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"
}
}Response from POST /api/a2a when a recruiter queries your agent.
{
"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
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.
/api/searchesCreate 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
/api/searches/:id/executeTrigger execution of a created search. Supports both session auth and x-api-key header.
Response 200
{ "status": "completed" }Errors: 401, 403, 404, 500
/api/searchesList 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
}/api/searches/:idPoll 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
/api/searches/:id/resultsGet 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
}/api/searches/:id/exportDownload 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.
/api/registry/searchBrowse 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=activeResponse 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
/api/registry/registerRegister 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
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
| Skill | Auth | Purpose |
|---|---|---|
candidate-search | x-api-key | Find matching candidates for a job description |
agent-registration | None | Returns instructions for registering via REST API |
recruiter-onboard | None | Provision a provisional API key |
send-message | x-api-key | Send a direct message to a candidate |
Request
{
"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)
{
"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
| Code | Meaning |
|---|---|
-32700 | Parse error (invalid JSON) |
-32600 | Invalid request (missing jsonrpc/method) |
-32601 | Method not found |
-32602 | Invalid params (missing required field) |
-32000 | Application error (auth, rate limit, DB failure) |
Rate Limits
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
| Endpoint | Limit |
|---|---|
GET /api/registry/search | 100/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.
| Code | Description |
|---|---|
| 400 | Bad request — missing or invalid fields (e.g. jobDescription too short) |
| 401 | Unauthenticated — no session cookie or API key provided |
| 403 | Forbidden — authenticated but role profile not found, or wrong role |
| 404 | Not found — search, agent, or resource does not exist |
| 409 | Conflict — agent endpoint already registered |
| 422 | Unprocessable — agent card could not be fetched or failed schema validation |
| 429 | Rate limit exceeded — wait Retry-After seconds before retrying |
| 500 | Internal server error — database or upstream failure |
Create your account to get an API key, or browse the docs to learn more about the A2A protocol.