Authentication
All API requests require authentication using a Bearer token. Include your API key in the Authorization header of every request.
Header
Authorization: Bearer your_api_key_here
Your API key is a 64-character hexadecimal string provided when your account is created. Keep your API key secure - do not share it in public repositories, client-side code, or unencrypted communications.
Security: Never expose your API key in front-end code. Always make API calls from your server-side application.
Endpoints
Skills Match
POST
/api/v1/match
Evaluate the match between a job description and a candidate profile. Returns a match score with a detailed breakdown across multiple dimensions.
Send a JSON payload with the following structure:
JSON
{
"job_description": "We are looking for a Senior PHP Developer with 5+ years experience in Laravel, MySQL, and REST APIs. Based in Johannesburg. BSc in Computer Science preferred.",
"candidate_profile": {
"skills": ["PHP", "Laravel", "MySQL", "REST APIs", "JavaScript", "Docker"],
"experience": "7 years of full-stack web development, 5 years specialising in PHP/Laravel",
"location": "Pretoria, Gauteng",
"education": "BSc Computer Science, University of Pretoria"
}
}
Request Fields
| Field |
Type |
Description |
| job_description |
string or object required |
The job description as raw text (AI will extract requirements) or a structured object with title, skills, location, experience, and education fields. |
| candidate_profile |
object required |
The candidate's profile information. |
| candidate_profile.skills |
array required |
Array of skill name strings (max 50). Use standard industry names. |
| candidate_profile.experience |
string optional |
Free-text description of the candidate's work experience. |
| candidate_profile.location |
string optional |
The candidate's location (city, province). SA locations work best. |
| candidate_profile.education |
string optional |
The candidate's education background. |
Structured Job Description
For faster processing and more accurate results, you can pass the job description as a structured object instead of raw text:
JSON
{
"job_description": {
"title": "Senior PHP Developer",
"skills": ["PHP", "Laravel", "MySQL", "REST APIs"],
"location": "Johannesburg, Gauteng",
"experience": "5+ years PHP development",
"education": "BSc Computer Science preferred"
},
"candidate_profile": {
"skills": ["PHP", "Laravel", "MySQL"],
"experience": "7 years web development",
"location": "Pretoria",
"education": "BSc Computer Science"
}
}
Tip: Structured job descriptions skip the AI extraction step, resulting in faster response times and lower latency.
All responses are returned as JSON with a consistent structure.
Success Response
200 OK
{
"success": true,
"match_score": 82,
"breakdown": {
"skills_match": 85,
"experience_match": 78,
"location_match": 70,
"education_match": 88
},
"recommendation": "Strong Match",
"meta": {
"request_id": "sr_660f8a3b2e4c71.23456789",
"response_time": "1240ms",
"remaining_calls": 847
}
}
Response Fields
| Field |
Type |
Description |
| success |
boolean |
Whether the request was processed successfully. |
| match_score |
integer |
Overall match score from 0-100. |
| breakdown |
object |
Score breakdown by category (each 0-100). |
| recommendation |
string |
Human-readable match quality label: "Excellent Match", "Strong Match", "Good Match", "Moderate Match", "Weak Match", or "Poor Match". |
| meta.request_id |
string |
Unique identifier for this request. Reference in support queries. |
| meta.response_time |
string |
Server-side processing time. |
| meta.remaining_calls |
integer |
Number of remaining API calls in the current billing month. |
Error Codes
When an error occurs, the response includes a machine-readable error code and a descriptive message.
Error Response Format
4xx/5xx
{
"success": false,
"error": {
"code": "INVALID_API_KEY",
"message": "The provided API key is not valid."
}
}
Error Code Reference
| HTTP Status |
Error Code |
Description |
| 400 |
INVALID_JSON |
Request body is not valid JSON. |
| 400 |
MISSING_FIELD |
A required field is missing or empty. |
| 400 |
FIELD_TOO_LONG |
A field exceeds its maximum allowed length. |
| 401 |
MISSING_AUTH |
The Authorization header was not provided. |
| 401 |
INVALID_AUTH_FORMAT |
The Authorization header format is incorrect. |
| 401 |
INVALID_API_KEY |
The API key is not recognized. |
| 403 |
CLIENT_SUSPENDED |
The API client account has been suspended or cancelled. |
| 403 |
IP_NOT_ALLOWED |
The request IP is not in the client's whitelist. |
| 405 |
METHOD_NOT_ALLOWED |
The endpoint only accepts POST requests. |
| 422 |
NO_SKILLS_FOUND |
Could not extract skills from the job description. |
| 429 |
RATE_LIMIT_EXCEEDED |
Monthly API call limit has been reached. |
| 500 |
EXTRACTION_FAILED |
AI extraction of job requirements failed. Try structured input. |
Rate Limits
API usage is tracked on a monthly billing cycle (1st to last day of each month). Each plan includes a set number of API calls per month.
| Plan |
Calls/Month |
Overage Rate |
| Professional |
1,000 |
R10.00 per call |
| Business |
5,000 |
R7.50 per call |
| Enterprise |
25,000 |
R4.00 per call |
| High-Volume |
100,000 |
R2.00 per call |
The meta.remaining_calls field in each successful response tells you how many calls you have left for the current month.
When your limit is reached, requests will return a 429 status with the RATE_LIMIT_EXCEEDED error code. Contact sales to upgrade your plan or discuss overage billing.
Usage Examples
cURL
Bash
curl -X POST https://skillrisecareers.co.za/api/v1/match \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"job_description": "Looking for a Senior React Developer with 3+ years experience. Must know TypeScript, Node.js, and REST APIs. Cape Town based.",
"candidate_profile": {
"skills": ["React", "TypeScript", "Node.js", "JavaScript", "CSS", "Git"],
"experience": "4 years of front-end development with React and TypeScript",
"location": "Cape Town, Western Cape",
"education": "National Diploma in IT, CPUT"
}
}'
JavaScript (fetch)
JavaScript
const response = await fetch('https://skillrisecareers.co.za/api/v1/match', {
method: 'POST',
headers: {
'Authorization': `Bearer ${API_KEY}`,
'Content-Type': 'application/json',
},
body: JSON.stringify({
job_description: {
title: 'Data Analyst',
skills: ['Python', 'SQL', 'Power BI', 'Excel'],
location: 'Johannesburg',
experience: '2+ years data analysis',
education: 'Degree in Statistics or related',
},
candidate_profile: {
skills: ['Python', 'SQL', 'Tableau', 'Excel', 'R'],
experience: '3 years as a junior data analyst at a financial services firm',
location: 'Sandton, Gauteng',
education: 'BCom Honours in Statistics, Wits University',
},
}),
});
const data = await response.json();
if (data.success) {
console.log(`Match Score: ${data.match_score}`);
console.log(`Recommendation: ${data.recommendation}`);
console.log('Breakdown:', data.breakdown);
} else {
console.error(`Error: ${data.error.code} - ${data.error.message}`);
}
PHP
PHP
$payload = json_encode([
'job_description' => 'Full-stack developer needed. PHP, Laravel, Vue.js, MySQL. Remote OK.',
'candidate_profile' => [
'skills' => ['PHP', 'Laravel', 'Vue.js', 'MySQL', 'Docker'],
'experience' => '6 years full-stack development',
'location' => 'Remote',
'education' => 'BSc Information Technology',
],
]);
$ch = curl_init('https://skillrisecareers.co.za/api/v1/match');
curl_setopt_array($ch, [
CURLOPT_POST => true,
CURLOPT_POSTFIELDS => $payload,
CURLOPT_RETURNTRANSFER => true,
CURLOPT_HTTPHEADER => [
'Authorization: Bearer YOUR_API_KEY',
'Content-Type: application/json',
],
]);
$response = curl_exec($ch);
$data = json_decode($response, true);
curl_close($ch);
if ($data['success']) {
echo "Match: " . $data['match_score'] . "% - " . $data['recommendation'];
}
Python
Python
import requests
response = requests.post(
'https://skillrisecareers.co.za/api/v1/match',
headers={
'Authorization': f'Bearer {API_KEY}',
'Content-Type': 'application/json',
},
json={
'job_description': 'Accountant needed. SAICA registered, 3+ yrs. Durban.',
'candidate_profile': {
'skills': ['Accounting', 'IFRS', 'Tax', 'Sage', 'Excel'],
'experience': '5 years at a mid-tier audit firm',
'location': 'Durban, KZN',
'education': 'BCom Accounting, SAICA CA(SA)',
},
},
)
data = response.json()
print(f"Score: {data['match_score']} - {data['recommendation']}")
Support
Need help integrating the API? Our team is here to assist.
When contacting support, please include:
- Your company name and API client ID
- The request_id from the response (if available)
- The full error response (code and message)
- A sample request payload (with sensitive data redacted)
Ready to Get Started?
Contact our sales team to set up your API account and receive your credentials.
Contact Sales
View Pricing