Randstad App data API: vacancies, payslips and timesheets
Randstad App - Buscar trabajo is the official Android app of Randstad España S.L.U., the Spanish operating company of the Dutch staffing group Randstad. Job seekers search vacancies across Spain, save alerts, and apply from a CV they keep in the app — personal details, experience, studies, languages, driving licences, NIF photos and other documents — then follow consultant job calls and active processes. Once placed, workers open nóminas and IRPF certificates, fill daily boletines (timesheets) with hours and absences, check vacation balances, and read PlanDay assigned and open shifts. Training sits in the same profile through Quick Learning paths and Fundación Randstad courses. It serves temporary and permanent candidates in Spain and sits next to InfoJobs, Job&Talent, Adecco and Indeed rather than a generic global board.
Staffing payslips expose payRollDate, nif, clientName and a downloadable code, while vacancy cards carry offerId, salaryfrom, salaryto and isUserSubscribed. Placed workers add daily hours on boletines keyed by kbTimesheetId, begHour and endHour, and PlanDay assigned shifts list shiftId, startDateTime, departmentName and location. Job-call cards add jobName, consultantEmail and orderLineId; contract records hold nationalInsuranceNumber and IBAN parts (iban, bankId, accountnumber). Saved alerts keep alertId, search and salaryMin; worker files list docTypeId and shortName.
ATS builders fold the vacancy feed into Spanish hiring pipelines; payroll ops match nómina rows to confirmed timesheet hours; workforce tools mirror PlanDay assignments. openData Studio turns those fields into callable open data.
Screenshots
API surface
The endpoints and request/response examples below are reconstructed from the app's interface — illustrative, not a live capture.
Sign in candidate account
POST
/v1/session/candidate-loginosintSigns the candidate in with email, pass, con and timestamp and returns accessToken, refreshToken, candidateId, accountId and jwt used on later myprofile calls.
Auth: Unauthenticated email/password body. Response accessToken is the Bearer on later candidate calls.
- pass
- con
- timestamp
- accessToken
- tokenType
- refreshToken
- candidateId
- accountId
- name
- expiresIn
- jwt
- privacyPolicyDate
POST /v1/session/candidate-login HTTP/1.1 Content-Type: application/json ApplicationName: AppCandidate device_info_app: 5.10.4 { "email": "[email protected]", "pass": "******", "con": "es", "timestamp": 1728048000 }{ "accessToken": "<access-token>", "tokenType": "Bearer", "refreshToken": "<refresh-token>", "candidateId": 8845123, "accountId": 552190, "email": "[email protected]", "name": "Ana García", "expiresIn": 3600, "jwt": "<jwt>", "privacyPolicyDate": "2026-03-01T00:00:00" }Search job offers
GET
/v1/vacanciesopendataPages OfferSearchDto vacancy cards (offerId, title, company, salary band, city/province, subscriber flags) for the search-results screen.
Auth: Bearer accessToken from POST /v1/session/candidate-login (tokenType Bearer). Also ApplicationName=AppCandidate and device_info_app=5.10.4.
- pagination
- page
- totalCount
- isHasNext
- result
- offerId
- title
- company
- date
- minSalary
- maxSalary
- salaryTypeName
- city
- province
- numSubscribers
- isUserSubscribed
- isUserFavorite
- isNewOffer
GET /v1/vacancies?page=1 HTTP/1.1 Authorization: Bearer <access-token> ApplicationName: AppCandidate device_info_app: 5.10.4{ "pagination": { "page": 1, "elements": 20, "totalCount": 1284, "pageCount": 20, "totalPages": 65, "isHasNext": true, "isHasPrev": false }, "result": [ { "offerId": 901234, "title": "Operario de almacén", "company": "Logística Norte S.A.", "date": "2026-09-20T10:15:00", "description": "Picking and packing on two shifts.", "isUserSubscribed": false, "isUserFavorite": false, "minSalary": 18500.0, "maxSalary": 21000.0, "salaryTypeId": 1, "salaryTypeName": "Bruto/año", "city": {"id": 28079, "name": "Madrid"}, "province": {"id": 28, "name": "Madrid"}, "numSubscribers": 42, "experienceYears": 1, "isNewOffer": true } ] }Fetch offer detail
GET
/v1/vacancies/{offerId}opendataReturns the full OfferDetailDto used by the offer screen: salaryfrom/salaryto, requirements, dates, subscriber flags and workModality.
Auth: Bearer accessToken from POST /v1/session/candidate-login (tokenType Bearer). Also ApplicationName=AppCandidate and device_info_app=5.10.4.
- offerId
- title
- description
- introduction
- companydept
- requirements
- conditions
- statusId
- begDate
- endDate
- jobNumber
- salaryfrom
- salaryto
- yearsExperience
- views
- inscribed
- hasScreeningQuestions
- isIsUserFavorite
- isIsUserSubscribed
- company
- city
- workModality
- journalType
GET /v1/vacancies/901234 HTTP/1.1 Authorization: Bearer <access-token> ApplicationName: AppCandidate{ "offerId": 901234, "title": "Operario de almacén", "description": "Picking and packing on two shifts.", "introduction": "Join the inbound team in Coslada.", "companydept": "Logística", "requirements": "Carretilla elevadora preferred.", "conditions": "Contrato temporal, jornada completa.", "statusId": "PUB", "begDate": "2026-10-01", "endDate": "2026-12-31", "jobNumber": 3, "salaryfrom": 18500.0, "salaryto": 21000.0, "yearsExperience": 1, "views": 318, "inscribed": 42, "hasScreeningQuestions": true, "isIsUserFavorite": false, "isIsUserSubscribed": false, "company": {"id": 4401, "name": "Logística Norte S.A."}, "city": {"id": 28079, "name": "Madrid"}, "province": {"id": 28, "name": "Madrid"}, "workModality": {"id": 1, "name": "Presencial"}, "journalType": {"id": 1, "name": "Completa"} }Apply to an offer
POST
/v1/vacancies/{offerId}/subscribeopendataSubmits OfferSubscriptionDto.workerId against the offer so the candidate is inscribed (subscribeOffer / apply path).
Auth: Bearer accessToken from POST /v1/session/candidate-login (tokenType Bearer). Also ApplicationName=AppCandidate and device_info_app=5.10.4.
- workerId
- offerId
POST /v1/vacancies/901234/subscribe HTTP/1.1 Authorization: Bearer <access-token> Content-Type: application/json { "workerId": 8845123 }{ "status": 204 }List my applications
GET
/v1/candidates/{candidateId}/applicationsopendataPages MyOffersDto applications with registrationStatusId, cvRead, titleOffer and the salary band the candidate applied under.
Auth: Bearer accessToken from POST /v1/session/candidate-login (tokenType Bearer). Also ApplicationName=AppCandidate and device_info_app=5.10.4.
- pagination
- result
- candidateId
- webOfferId
- registrationStatusId
- registrationDate
- cvRead
- titleOffer
- offerStatusId
- isUserSubscribed
- minSalary
- maxSalary
- salarayTypeName
GET /v1/candidates/8845123/applications?page=1 HTTP/1.1 Authorization: Bearer <access-token>{ "pagination": { "page": 1, "elements": 10, "totalCount": 4, "totalPages": 1, "isHasNext": false, "isHasPrev": false }, "result": [ { "candidateId": 8845123, "webAccountId": 552190, "webOfferId": 901234, "registrationStatusId": 2, "registrationDate": "2026-09-21T09:00:00", "cvRead": 1, "titleOffer": "Operario de almacén", "offerPublicationDateNoFormat": "2026-09-20T10:15:00", "offerStatusId": "PUB", "isUserSubscribed": true, "isUserFavorite": false, "minSalary": 18500.0, "maxSalary": 21000.0, "salaryTypeId": 1, "salarayTypeName": "Bruto/año" } ] }Read candidate base profile
GET
/v1/candidates/{candidateId}/profileosintLoads CandidateBaseDto identity, NIF, Seguridad Social number, IBAN parts and worker status for the profile home.
Auth: Bearer accessToken from POST /v1/session/candidate-login (tokenType Bearer). Also ApplicationName=AppCandidate and device_info_app=5.10.4.
- candidateid
- name
- surname1
- surname2
- nif
- nationalInsuranceNumber
- birthday
- mobilePhone
- iban
- bankid
- accountnumber
- workerStateId
- workerStatusId
- addressStreet
- addressCity
- zipcode
- pictureUrl
- curriculumVitaeUrl
- cvCount
- profileSummary
- jobtype
GET /v1/candidates/8845123/profile HTTP/1.1 Authorization: Bearer <access-token>{ "candidateid": 8845123, "name": "Ana", "surname1": "García", "surname2": "López", "email": "[email protected]", "nif": "12345678Z", "nationalInsuranceNumber": "281234567890", "birthday": "1992-04-12", "mobilePhone": "612345678", "mobilePrefix": "+34", "iban": "ES7620770024003102575766", "bankid": "2077", "sucursalid": "0024", "accountnumber": "3102575766", "workerStateId": "ACT", "workerStatusId": "DISP", "addressStreet": "Calle Mayor", "addressCity": "Madrid", "addressProvince": "Madrid", "zipcode": "28013", "pictureUrl": "https://cdn.example.com/p.jpg", "curriculumVitaeUrl": "https://cdn.example.com/cv.pdf", "cvCount": 2, "hasVideo": false, "profileSummary": "Warehouse operator, 4 years.", "jobtype": "STAF" }List saved job alerts
GET
/v1/candidates/watchesopendataReturns saved AlertDto / SearchHistoryDto watches (alertId, search, salaryMin/salaryMax, periocityId, offersCount) used by the alerts wizard.
Auth: Bearer accessToken from POST /v1/session/candidate-login (tokenType Bearer). Also ApplicationName=AppCandidate and device_info_app=5.10.4.
- alertId
- name
- periocityId
- creationDate
- lastSearchDate
- search
- jobType
- provinceId
- cityId
- salaryMin
- salaryMax
- salaryTypeId
- offersCount
- workModalityId
- isMagnet
GET /v1/candidates/watches HTTP/1.1 Authorization: Bearer <access-token> ApplicationName: AppCandidate[ { "alertId": 44120, "name": "Almacén Madrid", "periocityId": 1, "creationDate": "2026-08-12T09:00:00", "lastSearchDate": "2026-10-04T07:15:00", "search": "operario almacén", "jobType": "STAF", "provinceId": "28", "cityId": "28079", "salaryMin": 18000, "salaryMax": 22000, "salaryTypeId": 1, "offersCount": 18, "workModalityId": 1, "isMagnet": false } ]List payslips
GET
/v1/candidates/{candidateId}/payslipsopenfinancePages PayrollPagedDto nómina rows (payRollDate, nif, clientName, code) for the worker payrolls screen.
Auth: Bearer accessToken from POST /v1/session/candidate-login (tokenType Bearer). Also ApplicationName=AppCandidate and device_info_app=5.10.4.
- pagination
- result
- startDate
- endDate
- clientName
- payRollDate
- incidence
- generatedDate
- nif
- affiliationTypeId
- code
GET /v1/candidates/8845123/payslips HTTP/1.1 Authorization: Bearer <access-token>{ "pagination": { "page": 1, "elements": 12, "totalCount": 12, "totalPages": 1, "isHasNext": false, "isHasPrev": false }, "result": [ { "startDate": "2026-09-01T00:00:00", "endDate": "2026-09-30T00:00:00", "clientName": "Logística Norte S.A.", "payRollDate": "2026-09-30T00:00:00", "incidence": false, "generatedDate": "2026-10-02T08:00:00", "nif": "12345678Z", "affiliationTypeId": 1, "code": "NOM-2026-09-8845123" } ] }Download payslip file
GET
/v1/candidates/{candidateId}/payslips/{payrollCode}openfinanceDownloads the nómina PDF for a PayrollDto.code via getPayrollFile.
Auth: Bearer accessToken from POST /v1/session/candidate-login (tokenType Bearer). Also ApplicationName=AppCandidate and device_info_app=5.10.4.
- payrollCode
- contentType
- filename
GET /v1/candidates/8845123/payslips/NOM-2026-09-8845123 HTTP/1.1 Authorization: Bearer <access-token> Accept: application/pdf{ "contentType": "application/pdf", "payrollCode": "NOM-2026-09-8845123", "filename": "nomina-2026-09.pdf" }List IRPF certificates
GET
/v1/candidates/{candidateId}/tax-certsopenfinanceLists IrpfCertificateDto / IrpfResultDto tax certificates (id, generatedDate, nif, model) shown on the IRPF screen.
Auth: Bearer accessToken from POST /v1/session/candidate-login (tokenType Bearer). Also ApplicationName=AppCandidate and device_info_app=5.10.4.
- pagination
- result
- id
- generatedDate
- nif
- model
GET /v1/candidates/8845123/tax-certs HTTP/1.1 Authorization: Bearer <access-token>{ "pagination": { "page": 1, "elements": 2, "totalCount": 2, "totalPages": 1, "isHasNext": false, "isHasPrev": false }, "result": [ { "id": 2025.0, "generatedDate": "2026-01-20T00:00:00", "nif": "12345678Z", "model": 145 } ] }List worker documents
GET
/v1/candidates/{candidateId}/filesosintPages DocumentsPagedDto / DocumentDto rows (docTypeId, shortName, contractId, url) for NIF photos and other worker files.
Auth: Bearer accessToken from POST /v1/session/candidate-login (tokenType Bearer). Also ApplicationName=AppCandidate and device_info_app=5.10.4.
- pagination
- result
- begDate
- endDate
- docTypeId
- contractId
- archiveTypeId
- shortName
- templateId
- barcodeId
- url
GET /v1/candidates/8845123/files HTTP/1.1 Authorization: Bearer <access-token>{ "pagination": { "page": 1, "elements": 8, "totalCount": 8, "totalPages": 1, "isHasNext": false, "isHasPrev": false }, "result": [ { "begDate": "2026-09-01", "endDate": "2026-12-31", "docTypeId": "NIF", "contractId": 33120, "archiveTypeId": "ID", "shortName": "DNI anverso", "templateId": 12, "barcodeId": 0, "url": "https://cdn.example.com/nif-front.jpg" } ] }List monthly timesheets
GET
/v1/workers/{workerId}/hoursheetsopendataReturns NewsletterResultDto monthly boletines (kbTimesheetId, statusId, daily begHour/endHour) for the timesheet calendar.
Auth: Authorization: bearer {newsLetterAccessToken} issued after the candidate session is established.
- totalRows
- results
- begDate
- endDate
- kbTimesheetId
- timesheetId
- timesheetTypeId
- statusId
- processType
- proposeHours
- costCenterDescription01
- partesDetallesDiarios
- dateline
- begHour
- endHour
- breakHour
- isHolidayChk
- isAbsenceChk
GET /v1/workers/8845123/hoursheets?year=2026&month=9 HTTP/1.1 Authorization: bearer <newsletter-token>{ "totalRows": 1, "results": [ { "begDate": "2026-09-01", "endDate": "2026-09-30", "kbTimesheetId": 778001, "timesheetId": 778001, "timesheetTypeId": "STD", "statusId": 2, "processType": "MONTH", "proposeHours": "160", "costCenterDescription01": "Almacén Coslada", "partesDetallesDiarios": [ { "dateline": "2026-09-15", "begHour": "0800", "endHour": "1600", "breakHour": "0030", "isHolidayChk": false, "isAbsenceChk": false, "comments": "" } ] } ] }Confirm timesheet status
PUT
/v1/workers/{workerId}/hoursheets/{timesheetId}/state/{statusId}opendataSets the Killbol timesheet statusId after the worker confirms the month's hours (confirmMonthHours / status path).
Auth: Authorization: bearer {newsLetterAccessToken} issued after the candidate session is established.
- workerId
- timesheetId
- statusId
PUT /v1/workers/8845123/hoursheets/778001/state/3 HTTP/1.1 Authorization: bearer <newsletter-token>{ "workerId": 8845123, "timesheetId": 778001, "statusId": 3 }List contract holidays
GET
/v1/contracts/{contractId}/public-holidaysopendataReturns NewsletterHolidaysDto public-holiday rows (holidaysDate, holidaysDesc, autonomy) for the worker's contract calendar.
Auth: Authorization: bearer {newsLetterAccessToken} issued after the candidate session is established.
- holidaysDate
- holidaysDesc
- autonomy
GET /v1/contracts/33120/public-holidays HTTP/1.1 Authorization: bearer <newsletter-token>[ { "holidaysDate": "2026-10-12", "holidaysDesc": "Fiesta Nacional de España", "autonomy": "Nacional" }, { "holidaysDate": "2026-11-09", "holidaysDesc": "Almudena", "autonomy": "Madrid" } ]List assigned PlanDay shifts
GET
/v1/roster/{userId}/shifts/mineopendataLists ShiftDto assigned shifts (shiftId, startDateTime, departmentName, location, position, status) for the PlanDay calendar.
Auth: PlanDay client_id and client_secret headers plus authToken from the candidate session JWT.
- shiftId
- departmentName
- clientName
- employeeGroupName
- startDateTime
- endDateTime
- location
- position
- status
- openType
- sectionName
- multiShiftId
- comment
GET /v1/roster/8845123/shifts/mine?from=2026-10-01&to=2026-10-31 HTTP/1.1 client_id: <planday-client-id> authToken: <jwt>[ { "shiftId": 55001, "departmentName": "Inbound", "clientName": "Logística Norte S.A.", "employeeGroupName": "Almacén", "startDateTime": "2026-10-06T08:00:00", "endDateTime": "2026-10-06T16:00:00", "location": "Coslada", "position": "Operario", "status": "ASSIGNED", "openType": null, "sectionName": "Picking", "multiShiftId": 0, "comment": "" } ]List open PlanDay shifts
GET
/v1/roster/{userId}/shifts/availableopendataLists ShiftDto open shifts (shiftId, openType, startDateTime, location, position) the worker can reply to from PlanDay.
Auth: PlanDay client_id and client_secret headers plus authToken from the candidate session JWT.
- shiftId
- departmentName
- clientName
- employeeGroupName
- startDateTime
- endDateTime
- location
- position
- status
- openType
- sectionName
- multiShiftId
- comment
GET /v1/roster/8845123/shifts/available?from=2026-10-01&to=2026-10-31 HTTP/1.1 client_id: <planday-client-id> authToken: <jwt>[ { "shiftId": 55088, "departmentName": "Outbound", "clientName": "Logística Norte S.A.", "employeeGroupName": "Almacén", "startDateTime": "2026-10-08T16:00:00", "endDateTime": "2026-10-09T00:00:00", "location": "Coslada", "position": "Operario", "status": "OPEN", "openType": "VOLUNTARY", "sectionName": "Packing", "multiShiftId": 0, "comment": "Extra night cover" } ]List PlanDay availability
GET
/v1/roster/{userId}/windowsopendataReturns AvailabilityDto windows (availabilityType, startDateTime, endDateTime) the worker marked in PlanDay.
Auth: PlanDay client_id and client_secret headers plus authToken from the candidate session JWT.
- availabilityType
- startDateTime
- endDateTime
- portalParams
GET /v1/roster/8845123/windows?from=2026-10-01&to=2026-10-31 HTTP/1.1 client_id: <planday-client-id> authToken: <jwt>[ { "availabilityType": "AVAILABLE", "startDateTime": "2026-10-06T08:00:00", "endDateTime": "2026-10-06T16:00:00", "portalParams": [] } ]List consultant job calls
GET
/v1/candidates/{candidateId}/job-callsopendataLists JobCallDetailDto consultant calls (jobName, state, salary, schedule, orderLineId) the worker can accept or reject.
Auth: Bearer accessToken from POST /v1/session/candidate-login (tokenType Bearer). Also ApplicationName=AppCandidate and device_info_app=5.10.4.
- id
- state
- jobName
- companyId
- companyName
- clientName
- startDate
- endDate
- expirationDate
- salary
- address
- schedule
- consultantEmail
- mobilePhone
- orderLineId
- workerType
GET /v1/candidates/8845123/job-calls HTTP/1.1 Authorization: Bearer <access-token>[ { "id": 12044, "state": "PENDING", "jobName": "Operario de almacén", "companyId": 4401, "companyName": "Randstad España", "clientName": "Logística Norte S.A.", "startDate": "2026-10-06T08:00:00", "endDate": "2026-12-31T18:00:00", "expirationDate": "2026-10-05T18:00:00", "salary": "1.450 €/mes", "address": "Coslada, Madrid", "schedule": "08:00-16:00", "consultantEmail": "[email protected]", "mobilePhone": "612000111", "orderLineId": 99021, "workerType": "TEMP" } ]Read contract and bank details
GET
/v1/candidates/{candidateId}/contract-bankopenfinanceReturns ContractInfoDto / bankAccountNumber (iban, bankId, accountNumber) and nationalInsuranceNumber used on the contract-data screen.
Auth: Bearer accessToken from POST /v1/session/candidate-login (tokenType Bearer). Also ApplicationName=AppCandidate and device_info_app=5.10.4.
- name
- surname1
- surname2
- sexid
- nationalInsuranceNumber
- address
- bankAccountNumber
- iban
- bankId
- sucursalId
- accountNumber
- controlDigit
GET /v1/candidates/8845123/contract-bank HTTP/1.1 Authorization: Bearer <access-token>{ "name": "Ana", "surname1": "García", "surname2": "López", "sexid": "F", "nationalInsuranceNumber": "281234567890", "address": { "street": "Calle Mayor", "city": "Madrid", "zipcode": "28013" }, "bankAccountNumber": { "iban": "ES7620770024003102575766", "bankId": "2077", "sucursalId": "0024", "accountNumber": "3102575766", "controlDigit": "31" } }
Data categories
- job offers
- applications
- job alerts
- candidate profiles
- payslips
- tax certificates
- worker documents
- timesheets
- holidays
- shifts
- job calls
- contracts
Where teams use this data
Spanish ATS vacancy ingest
A hiring pipeline pulls Randstad offer cards (offerId, title, company, salaryfrom/salaryto, city, province, isUserSubscribed) and hydrates the offer-detail screen with requirements, workModality and hasScreeningQuestions before posting an apply with workerId.
Nómina vs hours reconciliation
Payroll ops join payslip rows (code, payRollDate, nif, clientName, startDate, endDate) to confirmed boletín timesheets (kbTimesheetId, timesheetId, begHour, endHour, statusId) so hours signed off in Killbol match the nómina PDF downloaded by payrollCode.
PlanDay shift calendar in WFM
A workforce tool mirrors assigned and open shifts (shiftId, startDateTime, endDateTime, departmentName, location, position, status, openType) and worker availability windows (availabilityType, startDateTime, endDateTime) into an on-site roster.
Placed-worker identity for payroll KYC
Onboarding checks read candidateid, nif, nationalInsuranceNumber, iban/bankId/accountnumber and contractInfo so the same worker who applied to an offer is the one paid on the nómina.
Frequently asked questions
Which vacancy fields does the Randstad App search return?
Each OfferDto carries offerId, title, company, minSalary, maxSalary, salaryTypeName, city, province, numSubscribers, isUserSubscribed and isUserFavorite. The detail call adds salaryfrom, salaryto, requirements, conditions, workModality, hasScreeningQuestions, begDate and endDate.
How does the app authenticate later calls?
Email/password sign-in returns accessToken, tokenType, refreshToken, candidateId and jwt. Later candidate calls send Authorization: Bearer plus ApplicationName=AppCandidate and device_info_app. Timesheet (boletín) calls use a separate newsLetterAccessToken; PlanDay roster calls send client_id, client_secret and an authToken from the session JWT.
Can I read payslips and signed hours, not only job ads?
Yes. The payslip list pages PayrollDto rows (payRollDate, nif, clientName, code) and the payrollCode download returns the PDF. Timesheets return kbTimesheetId, begHour, endHour and statusId, and IRPF certificates list id, generatedDate, nif and model.
Is this a public developer API?
No. These are first-party endpoints the signed-in candidate app uses. They are documented here as the data surface behind the screens, not as an open partner programme.
Topics
- randstad api
- randstad empleo
- randstad nómina
- randstad boletines
- spanish job api
- planday shifts randstad
- candidate payroll api
- randstad offerId
Need this app's data API integrated?
We deliver scoped integrations for any named app — from USD 500 with source-code handoff, or hosted access billed per call. Tell us the data you need.
- NDA + SOW on every engagement
- Delivery in 3–7 days
- Payment only after acceptance
- Work scoped to authorized use