Complete reference for HireSquire REST API. All endpoints, request/response formats, authentication, code examples in Python and JavaScript, webhooks, and rate limits.
REST API Complete Reference: Build Custom Hiring Integrations with HireSquire
The HireSquire REST API provides complete programmatic access to candidate screening, job management, and results retrieval. This reference covers all endpoints, request/response formats, authentication, and practical examples for building custom integrations.
https://hiresquireai.com/api/v1
Authentication
All API requests require a Bearer token in the Authorization header:
Authorization: Bearer YOUR_API_TOKEN
Generate API tokens from your HireSquire dashboard at Profile → API Tokens.
Security Best Practice: For production applications, store tokens in environment variables, not in code. Never commit tokens to version control.
Base Response Format
All responses follow a consistent structure:
{
"success": true,
"data": { ... },
"message": "Optional message"
}
// Error responses
{
"success": false,
"error": "Error message",
"errors": { ... } // Validation errors
}
Idempotency
To prevent duplicate screening jobs (and duplicate charges) due to network retries, HireSquire supports idempotency keys for all POST requests that create resources.
Header: Idempotency-Key: <uuid>
When you include an Idempotency-Key header, HireSquire will save the result of the first successful request. If another request with the same key is received within 24 hours, the original result is returned without re-processing or re-charging.
Endpoints
1. Create Screening Job
Submit a new candidate screening job.
POST /api/v1/jobs
Content-Type: application/json
Authorization: Bearer YOUR_TOKEN
Request Body
{
"title": "Senior Software Engineer",
"description": "We are looking for a Python developer with 5+ years experience...",
"resumes": [
{
"filename": "john_doe_resume.txt",
"content": "John Doe\nEmail: [email protected]\nExperience: 5 years Python..."
}
],
"leniency_level": 5,
"webhook_url": "https://your-app.com/webhook",
"webhook_conditions": {
"min_score": 80,
"only_top_n": 5,
"events": ["job.completed", "high_score_detected"]
}
}
Response (202 Accepted)
{
"message": "Job accepted for processing.",
"job_id": 123,
"status_url": "https://hiresquireai.com/api/v1/jobs/123",
"results_url": "https://hiresquireai.com/api/v1/jobs/123/results",
"status": "processing"
}
Validation Rules
| Field | Required | Rules |
|---|---|---|
| title | Yes | string, max 255 chars |
| description | Yes | string, min 50 chars |
| resumes | Yes | array, min 1, max 100 items |
| resumes[].filename | Yes | string, max 255 chars |
| resumes[].content | Yes* | string, min 50 chars (or use base64/file_url) |
| leniency_level | No | integer, 1-10, default 5 |
* Each resume must have at least one of: content, base64, or file_url
2. Get Job Status
Retrieve the current status of a screening job.
GET /api/v1/jobs/{job_id}
Response
{
"job_id": 123,
"title": "Senior Software Engineer",
"status": "processing", // "processing", "completed", "failed", "cancelled"
"leniency_level": 5,
"created_at": "2026-03-28T10:00:00Z",
"estimated_completion": "2026-03-28T10:02:00Z",
"candidate_count": 10,
"summary": {
"total_candidates": 10,
"qualified_count": 3,
"top_score": 92,
"average_score": 68.5
},
"results_url": null // null until completed
}
3. Get Results
Retrieve screening results once job is complete.
GET /api/v1/jobs/{job_id}/results?min_score=70&only_top_n=5
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| min_score | integer | Filter candidates by minimum score (0-100) |
| only_top_n | integer | Return only top N candidates by score |
| page | integer | Page number for pagination (default: 1) |
Response
{
"job_id": 123,
"title": "Senior Software Engineer",
"status": "completed",
"total_candidates": 10,
"per_page": 50,
"current_page": 1,
"last_page": 1,
"candidates": [
{
"id": 1,
"name": "John Doe",
"score": 92,
"summary": "Excellent match with 5 years Python experience...",
"status": "new",
"email": "[email protected]",
"phone": "+1234567890",
"linkedin_url": "https://linkedin.com/in/johndoe",
"interview_questions": [
"Describe your Python architecture...",
"How do you handle database migrations?",
"Explain your experience with Django REST framework",
"How do you optimize slow SQL queries?",
"Describe a complex problem you solved with Python"
],
"strengths": ["Python", "Django", "PostgreSQL"],
"weaknesses": ["Limited AWS experience"],
"contact_info": {
"email": "[email protected]",
"phone": "+1234567890",
"linkedin_url": "https://linkedin.com/in/johndoe"
},
"generated_outreach": {
"interview_questions": [
{"question": "Describe your Python architecture...", "seeking": "Technical depth"}
],
"icebreaker": "I noticed your impressive work on Open Source..."
},
"raw_analysis": {
"filename": "john_doe_resume.pdf",
"strengths": ["Python", "Django", "PostgreSQL"],
"weaknesses": ["Limited AWS experience"]
},
"user_notes": "Great candidate, schedule ASAP",
"processed_at": "2026-03-28T10:05:00Z"
}
]
}
4. List Jobs
List all screening jobs for your account.
GET /api/v1/jobs?status=completed&limit=20&page=1
Query Parameters
| Parameter | Type | Description |
|---|---|---|
| status | string | Filter by: processing, completed, failed, cancelled |
| since | date | Filter jobs created after this date |
| limit | integer | Results per page (1-100, default: 20) |
| page | integer | Page number |
5. Cancel Job
Cancel a processing job.
POST /api/v1/jobs/{job_id}/cancel
Response
{
"job_id": 123,
"status": "cancelled",
"message": "Job has been cancelled."
}
6. Compare Candidates
Compare multiple candidates side-by-side.
GET /api/v1/jobs/{job_id}/compare?ids=1,2,3
Response
{
"job_id": 123,
"compared_count": 3,
"top_candidate": "John Doe",
"top_score": 92,
"score_range": 15,
"candidates": [
{"id": 1, "name": "John Doe", "score": 92, "summary": "..."},
{"id": 2, "name": "Jane Smith", "score": 85, "summary": "..."},
{"id": 3, "name": "Bob Wilson", "score": 77, "summary": "..."}
]
}
7. Generate Email
Generate an email for a candidate.
POST /api/v1/jobs/{job_id}/generate-email
{
"candidate_id": 1,
"type": "invite",
"tone": "professional",
"custom_notes": "We loved your portfolio..."
}
Email Types
- invite - Interview invitation
- rejection - Kind rejection email
- keep-warm - Engaging follow-up for top candidates
- followup - Standard follow-up message
Response
{
"success": true,
"candidate_id": 1,
"candidate_name": "John Doe",
"email": {
"subject": "Interview Invitation: Senior Software Engineer at Your Company",
"body": "Dear John Doe,\n\nWe were very impressed by your background in Python...",
"type": "invite",
"tone": "professional"
}
}
8. Report Outcome
Report hiring outcome to improve AI accuracy.
POST /api/v1/jobs/{job_id}/outcome
{
"candidate_id": 1,
"outcome": "hired" // "hired", "rejected", "withdrawn"
}
Response
{
"success": true,
"message": "Outcome recorded successfully."
}
9. Webhook Test
Test a webhook endpoint.
POST /api/v1/webhooks/test
{
"url": "https://your-app.com/webhook"
}
10. Rate Limit Status
Check your current rate limit status.
GET /api/v1/rate-limit
// Response
{
"limit": 60,
"remaining": 45,
"reset_at": "2026-03-28T11:00:00Z",
"reset_in_seconds": 1800
}
Error Codes
| Status | Meaning | Action |
|---|---|---|
| 200 | Success | Process response |
| 202 | Accepted | Job submitted, poll for completion |
| 401 | Unauthorized | Check API token |
| 422 | Validation Error | Check request body |
| 425 | Too Early | Job still processing |
| 429 | Rate Limited | Wait and retry |
Code Examples
Python
import requests
BASE_URL = "https://hiresquireai.com/api/v1"
HEADERS = {"Authorization": "Bearer YOUR_TOKEN"}
def create_job(title, description, resumes):
response = requests.post(
f"{BASE_URL}/jobs",
json={
"title": title,
"description": description,
"resumes": resumes,
"leniency_level": 5
},
headers=HEADERS
)
response.raise_for_status()
return response.json()
def get_results(job_id, min_score=70):
response = requests.get(
f"{BASE_URL}/jobs/{job_id}/results",
params={"min_score": min_score},
headers=HEADERS
)
response.raise_for_status()
return response.json()
# Usage
job = create_job(
"Senior Engineer",
"Looking for Python expert...",
[{"filename": "resume.txt", "content": "..."}]
)
results = get_results(job["job_id"])
JavaScript/Node.js
const axios = require('axios');
const client = axios.create({
baseURL: 'https://hiresquireai.com/api/v1',
headers: {
'Authorization': 'Bearer YOUR_TOKEN',
'Content-Type': 'application/json'
}
});
async function createJob(title, description, resumes) {
const response = await client.post('/jobs', {
title,
description,
resumes,
leniency_level: 5
});
return response.data;
}
async function getResults(jobId, minScore = 70) {
const response = await client.get(`/jobs/${jobId}/results`, {
params: { min_score: minScore }
});
return response.data;
}
// Usage
const job = await createJob('Senior Engineer', 'Looking for Python...', [...]);
const results = await getResults(job.job_id);
cURL
# Create job
curl -X POST https://hiresquireai.com/api/v1/jobs \
-H "Authorization: Bearer YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"title": "Senior Engineer",
"description": "Looking for Python developer...",
"resumes": [{"filename": "resume.txt", "content": "..."}]
}'
# Get results
curl "https://hiresquireai.com/api/v1/jobs/123/results?min_score=80" \
-H "Authorization: Bearer YOUR_TOKEN"
Webhooks
Configure webhooks to receive notifications when screening completes:
// Request with webhook
{
"title": "Senior Engineer",
"description": "...",
"resumes": [...],
"webhook_url": "https://your-app.com/webhook",
"webhook_conditions": {
"min_score": 80,
"only_top_n": 5,
"events": ["job.completed", "high_score_detected"]
}
}
Webhook Events
- job.processing - Job started processing
- job.completed - Job finished
- job.failed - Job failed
- high_score_detected - Candidate scored above threshold
Security: Webhook payloads include an X-Webhook-Signature header. Verify this HMAC-SHA256 signature to ensure authenticity.
Rate Limits
The API is rate limited to ensure fair usage:
- 60 requests per minute for standard accounts
- Higher limits available for Enterprise plans
- Rate limit headers included in all responses
When rate limited, receive a 429 response. Implement exponential backoff:
import time
import requests
def make_request_with_retry(url, headers, max_retries=3):
for attempt in range(max_retries):
response = requests.get(url, headers=headers)
if response.status_code == 429:
wait_time = 2 ** attempt # Exponential backoff
time.sleep(wait_time)
continue
response.raise_for_status()
return response.json()
raise Exception("Max retries exceeded")
Next Steps
Now that you understand the API:
- Python SDK - Use our native Python library for easier integration
- MCP Server - Connect via Model Context Protocol
- CLI - Quick command-line interface for testing
- Webhooks - Build event-driven workflows
The REST API gives you full control over hiring automation. For most use cases, start with the Python SDK or CLI for faster integration, then switch to the API for advanced customization.
Agent API Keys & Prepaid Credits
In addition to standard user API tokens, HireSquire provides dedicated Agent API Keys with spend limits and a Prepaid Credits system for pay-as-you-go agent usage.
Agent API Keys (Cost Control for AI Agents)
Create dedicated API keys for AI agents with built-in spend controls:
POST /api/v1/agent-keys
Content-Type: application/json
Authorization: Bearer YOUR_TOKEN
Request Body
{
"name": "My Recruiting Agent",
"daily_spend_limit": 5.00,
"monthly_spend_limit": 100.00,
"lifetime_spend_limit": null,
"permissions": ["read", "screen", "email"]
}
All limits are in dollars ($0.01 = 1 credit). A daily_spend_limit of 5.00 means the agent can spend up to $5.00/day (500 credits).
Agent Key Endpoints
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/agent-keys | List all agent keys |
| POST | /api/v1/agent-keys | Create new agent key |
| GET | /api/v1/agent-keys/{id} | Get key details |
| GET | /api/v1/agent-keys/{id}/usage | Get detailed usage stats |
| PUT | /api/v1/agent-keys/{id} | Update spend limits |
| POST | /api/v1/agent-keys/{id}/regenerate | Regenerate key value |
| DELETE | /api/v1/agent-keys/{id} | Revoke/disable key |
Usage Webhook Events
Configure webhooks to receive notifications when agent keys approach their limits:
{
"event": "agent.usage_threshold_reached",
"timestamp": "2026-05-12T10:00:00Z",
"data": {
"agent_key_id": 1,
"agent_key_name": "My Agent",
"spent_amount": 0.01,
"current_balance": 25.49,
"period_spend": 4.00,
"threshold": 5.00,
"current_spend": 4.00,
"currency": "USD"
}
}
- threshold_reached - Spend threshold reached
- daily_limit - Daily limit hit
- monthly_limit - Monthly limit hit
- low_balance - Balance below $1 or 5% threshold
- credits_exhausted - All credits used
Prepaid Credits System
Purchase prepaid credits for pay-as-you-go agent usage without a subscription:
Credit Packs
| Pack | Price | Credits | Bonus | Per Candidate |
|---|---|---|---|---|
| Pouch | $5 | 500 | - | $0.01 |
| Satchel | $25 | 2,750 | +250 (10%) | $0.0089 |
| Chest | $100 | 12,000 | +2,000 (20%) | $0.0083 |
Credit Endpoints
| Method | Endpoint | Description |
|---|---|---|
| GET | /api/v1/credits/balance | Check current credit balance |
| GET | /api/v1/credits/transactions | View transaction history |
| GET | /api/v1/credits/packs | List available credit packs |
| POST | /api/v1/credits/checkout | Create Stripe checkout session |
| POST | /api/v1/credits/auto-reload/enable | Enable auto-reload |
| POST | /api/v1/credits/auto-reload/disable | Disable auto-reload |
| POST | /api/v1/credits/webhook/configure | Configure usage webhooks |
Auto-Reload
Enable auto-reload to automatically purchase more credits when balance falls below:
- $1 (minimum threshold)
- 5% of your largest single purchase (whichever is higher)
Bulk Job Submission
Submit up to 10 screening jobs in a single request:
POST /api/v1/jobs/bulk
{
"jobs": [
{"title": "Frontend Dev", "description": "...", "resumes": [...]},
{"title": "Backend Dev", "description": "...", "resumes": [...]}
]
}
Response includes array of job_id values for tracking each job.
Token Validation for Agents
Verify an API token is valid without consuming credits:
GET /api/v1/schema/validate
// Response
{
"valid": true,
"user": {
"id": 123,
"name": "Alex Agent",
"email": "[email protected]"
},
"credits": {
"balance": 25.50,
"formatted_balance": "$25.50",
"is_low": false,
"auto_reload_enabled": true
}
}
This endpoint is useful for AI agents to verify their credentials at startup before attempting to submit jobs.