# HireSquire Agent Skills

You have access to the HireSquire API for AI-powered candidate screening. This file teaches you how to use it effectively.

## Capabilities

- **Resume Analysis**: Analyze candidate resumes against job descriptions
- **Candidate Scoring**: Score candidates 1-100 based on job fit
- **Interview Questions**: Generate 5 personalized interview questions per candidate
- **Email Generation**: Create interview invites, rejection emails, keep-warm follow-ups, and interview follow-ups

## Authentication

All API requests require a Bearer token:

```
Authorization: Bearer YOUR_API_TOKEN
```

Tokens can be generated from the HireSquire dashboard at `/profile` under "API Tokens".

> **Security Note**: For production agents, prefer setting `HIRESQUIRE_API_TOKEN` environment variable instead of saving to config file. On shared systems, config files may expose your token in plaintext.

## Leniency Level

The `leniency_level` parameter (1-10) controls how strictly candidates are evaluated:

| Level | Description | Use Case |
|-------|-------------|----------|
| 1-3   | Lenient - Broader candidate pool | Entry roles, high-volume |
| 4-6   | Balanced - Reasonable match threshold | Standard hiring |
| 7-10  | Strict - Requires strong matches | Senior roles, niche skills |

Default is 5 (balanced). Higher values increase evaluation strictness.

## API Base URL

```
https://hiresquireai.com/api/v1
```

---

## Integration Methods

HireSquire supports multiple integration methods. Choose the best one for your agent:

| Method | Best For | Key Feature |
|--------|----------|-------------|
| **CLI** | OpenClaw, Claude Code, Codex | `hiresquire screen --json` |
| **REST API** | Web apps, custom integrations | Full control, webhooks |
| **MCP** | Claude Desktop, VS Code agents | JSON-RPC 2.0 |
| **Python SDK** | LangChain, AutoGen, Python agents | Native Python |

---

## Option 1: CLI (Recommended for Agents)

The fastest way to integrate with any CLI-capable agent.

### Installation & Quick Start

```bash
# Fastest: Use without installing (Recommended for Agents)
npx -y hiresquire-cli screen --title "Job Title" --description "..." --resumes ./resumes/

# Or install globally
npm install -g hiresquire-cli
```

### Quick Start

```bash
# Configure your API token
hiresquire init --token YOUR_API_TOKEN

# Submit a screening job
hiresquire screen --title "Senior PHP Developer" --description "Job description" --resumes ./resumes/

# Check status
hiresquire status --job 123

# Get results
hiresquire results --job 123 --min-score 80

# Generate email
hiresquire email --job 123 --candidate 456 --type invite

# Agent Health Check (verify token & credits)
hiresquire whoami --json
```

### JSON Output (For Agents)

All commands support `--json` for machine-readable output:

```bash
hiresquire screen --title "Senior PHP Developer" --description "Job description" --resumes ./resumes/ --json
```

### Watch Mode

Poll for completion automatically:

```bash
hiresquire screen --title "Senior PHP Developer" --description "Job description" --resumes ./resumes/ --watch
```

---

## Option 2: REST API

### Async Workflow (CRITICAL)

HireSquire uses **asynchronous processing** because resume screening takes time. You MUST follow this pattern:

#### Step 1: Submit Job

```json
POST /api/v1/jobs
{
  "title": "Senior PHP Developer",
  "description": "Looking for experienced PHP developer with Laravel experience...",
  "leniency_level": 7,
  "resumes": [
    {
      "filename": "john_doe_resume.pdf",
      "content": "John Doe\n5 years PHP experience\n..."
    }
  ]
}
```

**Response (202 Accepted)**:
```json
{
  "job_id": 123,
  "status_url": "https://hiresquireai.com/api/v1/jobs/123",
  "results_url": "https://hiresquireai.com/api/v1/jobs/123/results",
  "status": "processing"
}
```

**IMPORTANT**: Save the `job_id` for polling.

#### Step 2: Poll for Status

```json
GET /api/v1/jobs/123
```

Keep polling until `status` is `"completed"` or `"failed"`.

**Polling Strategy**:
- Wait 2-5 seconds between polls
- Use exponential backoff if rate limited (429 response)
- Max recommended wait: 5 minutes

#### Step 3: Get Results

Once status is `"completed"`:

```json
GET /api/v1/jobs/123/results
```

### Agent Health Check (WhoAmI)

Before starting a long-running screening job, agents should verify their token validity and credit balance:

```json
GET /api/v1/schema/validate
```

**Response (200 OK)**:
```json
{
  "valid": true,
  "user": { "id": 1, "name": "Alex Agent", "email": "alex@example.com" },
  "credits": {
    "balance": 25.50,
    "formatted_balance": "$25.50",
    "is_low": false,
    "auto_reload_enabled": true
  }
}
```

---

## Option 3: MCP Server

For agents that support the Model Context Protocol (Claude Desktop, VS Code AI assistants).

### Endpoint

```
https://hiresquireai.com/api/v1/mcp
```

### Protocol

JSON-RPC 2.0 over HTTP

### Available Tools

| Tool Category | Tools |
|---------------|-------|
| **Screening** | `create_screening`, `get_screening_status`, `get_results`, `cancel_screening_job` |
| **Candidates** | `generate_email`, `report_hiring_outcome` |
| **Calendar & Meetings** | `list_calendar_connections`, `create_calendar_connection`, `get_available_slots`, `create_interview`, `generate_meeting_link` |
| **Credits & Payments** | `get_credit_balance`, `estimate_screening_cost`, `purchase_credits`, `create_checkout_session`, `enable_auto_reload`, `disable_auto_reload`, `list_credit_packs`, `get_credit_transactions` |
| **Utilities** | `whoami`, `get_api_schema`, `test_webhook` |

---

## Calendar & Meeting Integrations

Automate interview scheduling by connecting calendar and meeting tools.

### Supported Tools

| Tool | Auth Method | Setup Time |
|------|------------|-------------|
| **Calendly** | API Key | 2 min |
| **Cal.com** | API Key | 2 min |

### CLI Commands (For Agents)

```bash
# Connect calendar tools (Calendly or Cal.com)
hiresquire calendar:connect calendly --token YOUR_TOKEN
hiresquire calendar:connect calcom --token YOUR_TOKEN

# List connections
hiresquire calendar:list

# Schedule interview (after screening)
hiresquire interviews:schedule --job 123 --candidate 456 --time "2026-04-28T10:00:00Z"
```

### REST API Endpoints

| Endpoint | Method | Description |
|----------|--------|-------------|
| `/api/v1/calendar/connections` | GET/POST/DELETE | Manage calendar connections |
| `/api/v1/calendar/slots` | GET | Get available time slots |
| `/api/v1/interviews` | GET/POST | List/create interviews |

### Python SDK Methods

```python
from hiresquire import HireSquire

client = HireSquire("TOKEN")

# Connect calendar
client.calendar.connect(
    provider="calendly",
    api_key="YOUR_TOKEN"
)

# Get available slots
slots = client.calendar.get_slots(
    provider="calendly",
    date="2026-04-27"
)

# Create interview
interview = client.calendar.create_interview(
    job_id=123,
    candidate_id=456,
    scheduled_at="2026-04-28T10:00:00Z"
)
```

### User-Specific Setup

**AI Agents (Claude Code, OpenClaw, Codex):**
- Use CLI with `--json` flag for parsing
- Store API keys in environment variables
- Automate connection via REST API in agent workflows

**Technical Managers:**
- Use web dashboard at `/profile/integrations` or CLI
- Configure webhooks for real-time updates: `POST /api/v1/credits/webhook/configure`
- Leverage Python SDK for custom automation

**Hiring Managers:**
- Navigate to Profile → Integrations in the web dashboard
- Follow on-screen prompts (no code required for Calendly/Cal.com)
- Paste your public scheduling link for ANY tool in Profile Settings

---

## Webhook Alternative

Instead of polling, you can configure a webhook:

```json
POST /api/v1/jobs
{
  "title": "Senior PHP Developer",
  "description": "Looking for experienced PHP developer...",
  "resumes": [...],
  "webhook_url": "https://your-agent.com/webhooks/hiresquire"
}
```

### Conditional Webhooks

Filter webhook events by score:

```json
{
  "webhook_url": "https://your-agent.com/webhook",
  "webhook_conditions": {
    "min_score": 80,
    "only_top_n": 5,
    "events": ["job.completed", "high_score_detected"]
  }
}
```

### Webhook Signature Verification

All webhooks include HMAC-SHA256 signatures for security:

```
X-Webhook-Signature: t=1712456789,v1=abc123def456
```

- `t`: Unix timestamp
- `v1`: HMAC-SHA256 signature

**Verification Steps for Agents:**
1. Check timestamp `t` is within 5 minutes (300s) to prevent replay attacks.
2. Reconstruct the signed payload: `timestamp + "." + raw_json_body`.
3. Compute HMAC-SHA256 using your secret.
4. Compare using a constant-time comparison.

Example verification code:
```python
import hmac, hashlib, time

def verify_webhook(body: bytes, signature: str, secret: str) -> bool:
    # signature is format: t=123,v1=abc
    parts = dict(p.split('=') for p in signature.split(','))
    if abs(time.time() - int(parts['t'])) > 300:
        return False
    # Reconstruct signed payload: timestamp + "." + JSON body
    signed_payload = f"{parts['t']}.".encode() + body
    expected = hmac.new(secret.encode(), signed_payload, hashlib.sha256).hexdigest()
    return hmac.compare_digest(expected, parts['v1'])
```

**Node.js Example:**
```javascript
const crypto = require('crypto');

function verifyWebhook(body, signature, secret) {
    // signature is format: t=123,v1=abc
    const parts = Object.fromEntries(
        signature.split(',').map(p => p.split('='))
    );
    
    // Check timestamp (within 5 minutes)
    if (Math.abs(Date.now() / 1000 - parseInt(parts.t)) > 300) {
        return false;
    }
    
    // Reconstruct signed payload: timestamp + "." + raw JSON body string
    const signedPayload = `${parts.t}.${body}`;
    const expected = crypto
        .createHmac('sha256', secret)
        .update(signedPayload)
        .digest('hex');
        
    // Constant-time comparison
    return crypto.timingSafeEqual(
        Buffer.from(expected), 
        Buffer.from(parts.v1)
    );
}
```

---

## Error Handling

| Status Code | Meaning | Action |
|-------------|---------|--------|
| 202 | Job accepted, processing | Poll for status |
| 200 | Success | Process response |
| 401 | Unauthorized | Check your API token |
| 402 | Payment Required | Agent spend limit exceeded |
| 403 | Forbidden | Plan screening limit exceeded |
| 422 | Validation error | Check request body |
| 429 | Rate Limited | Wait and retry |

---

## Troubleshooting Guide

### Common Issues and Solutions

#### Authentication Errors

**401 Unauthorized**
- Verify your API token is correct
- Check token hasn't expired in dashboard
- Ensure using `Bearer YOUR_TOKEN` format (not just the token string)

**403 Forbidden**
- Token exists but lacks permissions
- Contact support to verify API access is enabled

#### Job Submission Errors

**422 Validation Error**
- Check `title` is provided (required)
- Check `description` is at least 50 characters
- Ensure `resumes` array has at least 1 resume with content
- Each resume needs `filename` and `content` (or `base64` or `file_url`)

**Empty Results**
- Resumes must contain at least 50 characters of parseable text
- Try raw text format if PDF/DOCX parsing fails

#### Polling Issues

**Job Stuck on "processing"**
- Check system status at status.hiresquireai.com
- For jobs > 5 minutes, cancel and resubmit with fewer resumes
- Consider using webhooks instead of polling for large batches

**Timeout Errors**
- Default timeout is 5 minutes (300 seconds)
- For large resume batches, use webhooks instead
- Use `--watch` flag in CLI with longer timeout if needed

#### Rate Limiting

**429 Too Many Requests**
- Wait before retrying (check `retry-after` header)
- Implement exponential backoff in your polling loop
- Consider batching requests if doing high-volume screening

### Debugging Tips

1. **Enable verbose logging**: Use `--verbose` flag in CLI
2. **Check API response**: Add `--json` for machine-readable output
3. **Test connection**: Run `hiresquire status --job 1` to verify auth
4. **Verify resume parsing**: Use CLI to submit single resume first

---

## Credit Management

All interfaces include full credit management:

```bash
# CLI Example
hiresquire credits --action balance          # Check balance
hiresquire credits --action list-packs       # View available packs
hiresquire credits --action auto-reload-enable --threshold 1 --amount 5 --payment-method-id pm_123
```

**Auto-reload for Agents:** This is the best way to avoid interruptions. Enable once and your agent will never get "insufficient credits" errors mid-screening.

## Tips for Agents

1. **Use CLI**: For OpenClaw, Claude Code, Codex - the CLI is the fastest integration
2. **Use Webhooks**: For batches > 10 resumes, webhooks avoid timeout issues
3. **Use MCP**: For Claude Desktop or VS Code agents - native JSON-RPC support
4. **Enable Auto-reload**: Configure once, never get interrupted for payment approval
5. **Batch Resumes**: Up to 100 resumes per job (limit applies to all plans)
6. **JSON Output**: Always use `--json` flag for reliable parsing

---

## Support

- **CLI Docs**: https://hiresquireai.com/docs/cli
- **API Docs**: https://hiresquireai.com/docs/api
- **Agent Docs**: https://hiresquireai.com/docs/agents
- **CLI Source**: https://github.com/bp46/hiresquire
- **Python SDK Source**: https://github.com/bp46/hiresquire
- **Email**: info@hiresquireai.com
