Skip to main content

List Candidates

NL EN

Updated June 15, 2026

GET /api/v1/candidates
curl -X GET \
  "https://app.recruitsome.com/api/v1/candidates" \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Accept: application/json"
const response = await fetch('https://app.recruitsome.com/api/v1/candidates', {
  method: 'GET',
  headers: {
    'Authorization': 'Bearer YOUR_API_KEY',
    'Accept': 'application/json',
  },
});

const data = await response.json();
console.log(data);
use Illuminate\Support\Facades\Http;

$response = Http::withToken('YOUR_API_KEY')
    ->acceptJson()
    ->get('https://app.recruitsome.com/api/v1/candidates');

$data = $response->json();

Retrieve a paginated list of candidates associated with a specific user. Candidates are scoped to the user's repository — only candidates that have been associated with the given user are returned.

Authentication

Requires an API key with the candidates:read scope (included in the Chrome Plugin preset). Calls with a key that lacks the scope return a 403 with error code INSUFFICIENT_SCOPE.

Endpoint

Code
GET /api/v1/candidates

Query Parameters

ParameterTypeDefaultDescription
user_idinteger-Required. The tenant user ID whose candidate repository to query
emailstring-Filter by exact email address match
searchstring-Search in first name, last name, and email (partial match)
statusstring-Filter by candidate status (see Status Values below)
sortstringcreated_atSort field: created_at, first_name, last_name, email
sort_directionstringdescSort direction: asc or desc
pageinteger1Page number for pagination
per_pageinteger20Items per page (max: 100)

Status Values

ValueDescription
potentialNew candidate, not yet contacted
waiting_for_intakeContacted and interested, awaiting intake
intake_scheduledIntake meeting has been planned
active_mediationActively being placed in procedures
latent_mediationAvailable but not actively being placed
upcoming_employeeAccepted an offer, starting soon
employeeCurrently employed
ex_employeeFormer employee
do_not_contactShould not be contacted

Response Fields

FieldTypeDescription
idintegerUnique candidate ID
slugstringURL-friendly identifier
first_namestringFirst/given name
middle_namestring|nullMiddle name or prefix
last_namestringLast/family name
full_namestringComputed full name
emailstringEmail address
mobile_phonestring|nullMobile phone number, formatted for display
fixed_phonestring|nullLandline phone number in raw E.164 format (e.g., +31201234567)
statusobjectCurrent candidate status
localitystring|nullCity/town
country_codestring|nullISO 3166-1 alpha-2 country code
linkedin_urlstring|nullLinkedIn profile URL
profile_completenessinteger|nullProfile completeness percentage (0-100)
avatarobjectAvatar image URLs
created_atstringISO 8601 creation date
updated_atstringISO 8601 last update date

Object Structures

Status Object

JSON
{
  "value": "potential",
  "label": "Potential Candidate"
}

Avatar Object

JSON
{
  "small": "https://app.recruitsome.com/media/candidates/42/conversions/avatar-thumb.jpg",
  "medium": "https://app.recruitsome.com/media/candidates/42/conversions/avatar-medium.jpg",
  "large": "https://app.recruitsome.com/media/candidates/42/conversions/avatar-large.jpg"
}

Avatar URLs may be null if the candidate has no profile photo.

Pagination

The response includes standard pagination metadata:

JSON
{
  "data": [...],
  "links": {
    "first": "https://app.recruitsome.com/api/v1/candidates?page=1",
    "last": "https://app.recruitsome.com/api/v1/candidates?page=3",
    "prev": null,
    "next": "https://app.recruitsome.com/api/v1/candidates?page=2"
  },
  "meta": {
    "current_page": 1,
    "from": 1,
    "last_page": 3,
    "path": "https://app.recruitsome.com/api/v1/candidates",
    "per_page": 20,
    "to": 20,
    "total": 52
  }
}

Example Request

Basic Request

curl -X GET "https://app.recruitsome.com/api/v1/candidates?user_id=1" \
  -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch(
  'https://app.recruitsome.com/api/v1/candidates?user_id=1',
  {
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY'
    }
  }
);

const data = await response.json();
console.log(data);
import requests

response = requests.get(
    'https://app.recruitsome.com/api/v1/candidates',
    params={'user_id': 1},
    headers={'Authorization': 'Bearer YOUR_API_KEY'}
)

data = response.json()
print(data)

Find Candidate by Email

curl -X GET "https://app.recruitsome.com/api/v1/candidates?user_id=1&[email protected]" \
  -H "Authorization: Bearer YOUR_API_KEY"
const response = await fetch(
  'https://app.recruitsome.com/api/v1/candidates?user_id=1&[email protected]',
  {
    headers: {
      'Authorization': 'Bearer YOUR_API_KEY'
    }
  }
);
response = requests.get(
    'https://app.recruitsome.com/api/v1/candidates',
    params={
        'user_id': 1,
        'email': '[email protected]'
    },
    headers={'Authorization': 'Bearer YOUR_API_KEY'}
)

With Filters

Bash
curl -X GET "https://app.recruitsome.com/api/v1/candidates?user_id=1&search=developer&status=active_mediation&sort=last_name&sort_direction=asc" \
  -H "Authorization: Bearer YOUR_API_KEY"

Example Response

JSON
{
  "data": [
    {
      "id": 42,
      "slug": "john-doe-amsterdam",
      "first_name": "John",
      "middle_name": null,
      "last_name": "Doe",
      "full_name": "John Doe",
      "email": "[email protected]",
      "mobile_phone": "+31 6 12345678",
      "fixed_phone": null,
      "status": {
        "value": "potential",
        "label": "Potential Candidate"
      },
      "locality": "Amsterdam",
      "country_code": "NL",
      "linkedin_url": "https://linkedin.com/in/johndoe",
      "profile_completeness": 75,
      "avatar": {
        "small": "https://app.recruitsome.com/media/candidates/42/conversions/avatar-thumb.jpg",
        "medium": "https://app.recruitsome.com/media/candidates/42/conversions/avatar-medium.jpg",
        "large": "https://app.recruitsome.com/media/candidates/42/conversions/avatar-large.jpg"
      },
      "created_at": "2024-01-15T09:00:00+00:00",
      "updated_at": "2024-01-20T14:30:00+00:00"
    }
  ],
  "links": {
    "first": "https://app.recruitsome.com/api/v1/candidates?page=1",
    "last": "https://app.recruitsome.com/api/v1/candidates?page=1",
    "prev": null,
    "next": null
  },
  "meta": {
    "current_page": 1,
    "from": 1,
    "last_page": 1,
    "path": "https://app.recruitsome.com/api/v1/candidates",
    "per_page": 20,
    "to": 1,
    "total": 1
  }
}

Errors

StatusWhenBody
422user_id is missing or doesn't reference an existing user{"message": "The given data was invalid.", "errors": {"user_id": ["The user id field is required."]}}
422email filter isn't a valid email address, or search exceeds 255 charactersSame shape, with the offending field in errors
401Missing or invalid API key{"message": "Unauthenticated."}
403API key lacks the candidates:read scope{"message": "This API key does not have the required permission: candidates:read", "error": "INSUFFICIENT_SCOPE", "required_scope": "candidates:read"}

Notes

  • The user_id parameter is required — candidates are scoped to a specific user's repository
  • Only candidates that have been associated with the given user are returned
  • Soft-deleted candidates are automatically excluded
  • The email filter performs an exact match; use search for partial matching
  • The search parameter performs a case-insensitive partial match across first name, last name, and email
  • mobile_phone is returned formatted for display; fixed_phone is returned as a raw E.164 string
  • Avatar URLs may be null if the candidate has no profile photo uploaded