Vocations
Documentación
Integra el rastreo de vacantes y la información empresarial directamente en tu flujo de trabajo de selección.
Autenticación
Todos los endpoints bajo /v2 requieren una clave de API válida, incluidos los que no consumen créditos.
Los endpoints de la ruta /playground no requieren clave de API.
En el caso de los endpoints /v2, la clave debe indicarse en el encabezado HTTP «Authorization» con el valor «Bearer <clave>».
Authorization: Bearer 5tg••••••••••••••••8ux
Tipos compartidos
? Cuando aparece «?» después de una clave, el valor es opcional.[] «[]» después de cualquier tipo indica que el valor debe ser un array.
Todos los identificadores tienen una longitud de 16 caracteres.
Los endpoints de búsqueda aceptan page (empieza en 0, valor por defecto 0) y pageSize (mínimo 1, máximo 128, valor por defecto 10).
Los arrays de filtros aceptan hasta 64 elementos, salvo names, cities, provinces, regions, nations, postalCodes, italy.ivas, italy.ateco, spain.cifNifs y spain.cnae, que aceptan hasta 256. Los endpoints por lotes aceptan entre 1 y 128 identificadores. Superar un límite devuelve 400.
Cada respuesta autenticada devuelve X-RateLimit-Limit, X-RateLimit-Remaining y X-RateLimit-Reset para la ventana del minuto actual. Un 429 también devuelve Retry-After.
type ErrorResponse = { message: string };
type CountryKey = "italy" | "spain";
type LocationLevel = {
level: 4 | 6 | 8;
value: string;
};
type LocationFilter = {
country: CountryKey;
levels: LocationLevel[];
};
type Location = {
city?: string;
province?: string;
region?: string;
nation?: string;
latitude?: number;
longitude?: number;
};
type PendingStatus =
| "idle"
| "pending"
| "completed"
| "notAvailable"
| "failed";
type NumericRange =
| { min: number; max: number }
| { min: number; max?: undefined }
| { min?: undefined; max: number };
type YearlySalaryRange = {
min?: number;
max?: number;
currency: string;
};
type YearlyValue = {
year: number;
value: number;
};
type SortType =
| "default"
| "name"
| "city"
| "province"
| "region"
| "sectors"
| "currentTotalRevenue"
| "currentEmployees"
| "currentOpenPositions";
type SortOrder = "asc" | "desc";
type PositionSource = "vocations" | "linkedIn" | "indeed" | "infoJobs";
type Hours = "full" | "part" | "shift";
type CompanyStatus = "open" | "bankruptcy" | "liquidation";
type ValueTrend = "increasing" | "decreasing" | "stable";
type ExperienceLevel = "0" | "0-1" | "1-3" | "3-5" | "5-10" | "10+";
type Contract =
| "temporary"
| "internship"
| "permanent"
| "contract"
| "apprenticeship"
| "freelance";
type Collar = "blue" | "white";
type SmartWorking = "yes" | "no" | "hybrid";
type BusinessUnit =
| "finance"
| "hr"
| "purchasing"
| "marketing"
| "sales"
| "customerService"
| "research"
| "operations"
| "it"
| "legal"
| "strategy"
| "sustainability"
| "administration";
type SectorKey =
| "administrationAccounting"
| "textileClothing"
| "mediaCommunicationMarketing"
| "aeronauticsNavalDefense"
| "realEstate"
| "agriculture"
| "horeca"
| "food"
| "artHistoryArchitecture"
| "furniture"
| "craftsmanship"
| "insurance"
| "socialCooperativesAssociations"
| "automotive"
| "banking"
| "biomedical"
| "broadcastingMusicFilm"
| "outsourcingBusinessServices"
| "retail"
| "manufacturingIndustrial"
| "chemical"
| "energyOilGas"
| "trade"
| "consultingITConsulting"
| "consumerGoods"
| "pharmaceutical"
| "environmentSustainabilityEcology"
| "publishing"
| "educationTraining"
| "electronicsElectrotechnics"
| "industrialEngineeringServices"
| "sportsCultureEntertainment"
| "publicEntitiesNonProfitPublicAdmin"
| "financeFinancialServices"
| "gamingBetting"
| "rubberPlastic"
| "largeScaleRetail"
| "healthHygiene"
| "humanResources"
| "warehousePackaging"
| "cybersecurityIT"
| "legalCompliance"
| "logistics"
| "transportShipping"
| "medical"
| "metallurgyMechanics"
| "exhibitionsFairsEvents"
| "motors"
| "cleaning"
| "securitySurveillance"
| "personalServices"
| "professionalFirm"
| "telecommunications"
| "tourismTravel"
| "designFashion"
| "multiservices"
| "technologyScienceData"
| "automation"
| "other";
type ItalyLegalForm =
| "AA"
| "AC"
| "AE"
| "AF"
| "AI"
| "AL"
| "AM"
| "AN"
| "AP"
| "AR"
| "AS"
| "AT"
| "AU"
| "AZ"
| "CC"
| "CE"
| "CF"
| "CI"
| "CL"
| "CM"
| "CN"
| "CO"
| "CR"
| "CS"
| "CZ"
| "DI"
| "EC"
| "ED"
| "EE"
| "EI"
| "EL"
| "EM"
| "EN"
| "EP"
| "ER"
| "ES"
| "FI"
| "FO"
| "GE"
| "IC"
| "ID"
| "IF"
| "IR"
| "LL"
| "MA"
| "OC"
| "OO"
| "OS"
| "PA"
| "PC"
| "PF"
| "PS"
| "RC"
| "RR"
| "RS"
| "SA"
| "SC"
| "SD"
| "SE"
| "SF"
| "SG"
| "SI"
| "SL"
| "SM"
| "SN"
| "SO"
| "SP"
| "SR"
| "SS"
| "ST"
| "SU"
| "SV"
| "SZ";
type SpainLegalForm =
| "GE"
| "IE"
| "IU"
| "PO"
| "AC"
| "CJ"
| "CB"
| "CD"
| "BI"
| "PH"
| "CG"
| "CL"
| "EX"
| "PV"
| "NL"
| "NR"
| "PJ"
| "FN"
| "FJ"
| "FD"
| "MT"
| "MU"
| "OA"
| "PP"
| "AG"
| "SM"
| "SA"
| "ES"
| "SD"
| "SE"
| "SB"
| "SF"
| "SU"
| "CV"
| "CP"
| "CO"
| "CA"
| "CS"
| "SC"
| "SG"
| "GR"
| "LD"
| "SL"
| "LL"
| "LP"
| "NE"
| "LF"
| "LU"
| "UC"
| "UT"
| "OR";Códigos de formas jurídicas
Las formas jurídicas utilizan códigos específicos para cada país. Despliega un país para ver el significado oficial de cada valor aceptado y devuelto por la API.
Usa estos códigos en italy.legalForms o spain.legalForms al realizar búsquedas. El enriquecimiento de empresas devuelve un único código en italy.legalForm o spain.legalForm.
Italia · ItalyLegalForm (73 valores)
| Código | Significado |
|---|---|
| AA | Società in accomandita per azioni (S.a.p.A.) |
| AC | Associazione |
| AE | Società consortile in accomandita semplice |
| AF | Altre forme |
| AI | Associazione impresa |
| AL | Azienda speciale di ente locale |
| AM | Azienda municipale |
| AN | Società consortile in nome collettivo |
| AP | Azienda provinciale |
| AR | Azienda regionale |
| AS | Società in accomandita semplice (S.a.s.) |
| AT | Azienda autonoma statale |
| AU | Società per azioni con socio unico |
| AZ | Azienda speciale |
| CC | Consorzio con attività esterna |
| CE | Comunione ereditaria |
| CF | Consorzio fidi |
| CI | Società cooperativa a responsabilità illimitata |
| CL | Società cooperativa a responsabilità limitata |
| CM | Consorzio municipale |
| CN | Società consortile |
| CO | Consorzio |
| CR | Consorzio intercomunale |
| CS | Consorzio senza attività esterna |
| CZ | Consorzio di cui al D.Lgs. 267/2000 |
| DI | Impresa individuale |
| EC | Ente pubblico commerciale |
| ED | Ente diritto pubblico |
| EE | Ente ecclesiastico |
| EI | Ente impresa |
| EL | Ente sociale |
| EM | Ente morale |
| EN | Ente |
| EP | Ente pubblico economico |
| ER | Ente ecclesiastico civilmente riconosciuto |
| ES | Ente di cui alla L.R. 21-12-93 N.88 |
| FI | Fondazione impresa |
| FO | Fondazione |
| GE | Gruppo europeo di interesse economico (GEIE) |
| IC | Istituto di credito |
| ID | Istituto di credito di diritto pubblico |
| IF | Impresa familiare |
| IR | Istituto religioso |
| LL | Azienda speciale di cui al D.Lgs. 267/2000 |
| MA | Mutua assicurazione |
| OC | Società cooperativa consortile |
| OO | Cooperativa sociale |
| OS | Società consortile cooperativa a responsabilità limitata |
| PA | Associazione in partecipazione |
| PC | Piccola società cooperativa |
| PF | Persona fisica |
| PS | Piccola società cooperativa a responsabilità limitata |
| RC | Contratto di rete dotato di soggettività giuridica |
| RR | Società a responsabilità limitata a capitale ridotto |
| RS | Società a responsabilità limitata semplificata (S.r.l.s.) |
| SA | Società anonima |
| SC | Società cooperativa (Soc. Coop.) |
| SD | Società europea |
| SE | Società semplice (S.s.) |
| SF | Società di fatto |
| SG | Società cooperativa europea (SCE) |
| SI | Società irregolare |
| SL | Società consortile a responsabilità limitata |
| SM | Società di mutuo soccorso |
| SN | Società in nome collettivo (S.n.c.) |
| SO | Società consortile per azioni |
| SP | Società per azioni (S.p.A.) |
| SR | Società a responsabilità limitata (S.r.l.) |
| SS | Società costituita in base a leggi di altro stato |
| ST | Soggetto estero |
| SU | Società a responsabilità limitata con unico socio |
| SV | Società tra professionisti (S.t.p.) |
| SZ | Società non prevista dalla legislazione italiana |
España · SpainLegalForm (51 valores)
| Código | Significado |
|---|---|
| GE | Agrup. Eur. de Interés Económico |
| IE | Agrupación de Interés Económico |
| IU | Agrupación de Interés Urbanístico |
| PO | Agrupación Portuaria de Interés Económico |
| AC | Asociación |
| CJ | Caja |
| CB | Club Deportivo Básico |
| CD | Club Deportivo Elemental |
| BI | Comunidad de Bienes |
| PH | Comunidad de Propietarios en Régimen de Propiedad Horizontal |
| CG | Congregación o Institución Religiosa |
| CL | Corporación Local |
| EX | Empresa Extranjera |
| PV | Entidad de Previsión Social Voluntaria |
| NL | Entidad no Lucrativa |
| NR | Entidad no Residente |
| PJ | Entidad sin personalidad jurídica |
| FN | Fondo |
| FJ | Forma jurídica sin identificar |
| FD | Fundación |
| MT | Mutua |
| MU | Mutualidad de Previsión Social |
| OA | Organismo Autónomo |
| PP | Partido Político |
| AG | Sociedad Agraria de Transformación |
| SM | Sociedad Anonima Municipal |
| SA | Sociedad Anónima |
| ES | Sociedad Anónima de Gestión de Estibadores Portuarios |
| SD | Sociedad Anónima Deportiva |
| SE | Sociedad Anónima Europea |
| SB | Sociedad Anónima Laboral |
| SF | Sociedad Anónima Profesional |
| SU | Sociedad Anónima Unipersonal |
| CV | Sociedad Civil |
| CP | Sociedad Civil Profesional |
| CO | Sociedad Colectiva / Sociedad de Responsabilidad Colectiva |
| CA | Sociedad Comanditaria por Acciones |
| CS | Sociedad Comanditaria Simple / Sociedad en Comandita |
| SC | Sociedad Cooperativa |
| SG | Sociedad Cooperativa Europea |
| GR | Sociedad de Garantía Recíproca |
| LD | Sociedad Limitada |
| SL | Sociedad Limitada |
| LL | Sociedad Limitada Laboral |
| LP | Sociedad Limitada Laboral Profesional |
| NE | Sociedad Limitada Nueva Empresa |
| LF | Sociedad Limitada Profesional |
| LU | Sociedad Limitada Unipersonal |
| UC | Sucursal en España |
| UT | Unión Temporal de Empresas |
| OR | Órgano de la Administración |
Entorno de pruebas
Usa el entorno de pruebas para explorar los endpoints sin necesidad de clave de API. La ruta base es https://vocations.io/api/playground, replica exactamente los endpoints v2 y funciona con datos sintéticos italianos y españoles.
curl -X POST https://vocations.io/api/playground/companies \
-H "Content-Type: application/json" \
-d '{
"page": 0,
"company": {
"locations": [
{
"country": "spain",
"levels": [{ "level": 4, "value": "Cataluña" }]
}
],
"sectors": ["technologyScienceData"],
"employees": [{ "min": 11, "max": 200 }]
},
"sortType": "name",
"sortOrder": "asc",
"withPositions": true
}'{
"companyIDs": [
"pc0000000000000f",
"pc0000000000001j",
"pc0000000000002b"
],
"totalPages": 22,
"totalResults": 217
}Empresas
POST /companies
✓ No consume créditosSolicitud
type APICompanyFilter = {
ids?: string[];
parentHoldingIDs?: string[];
names?: string[];
workAgency?: boolean;
locations?: LocationFilter[];
postalCodes?: string[];
italy?: {
ivas?: string[];
ateco?: string[];
legalForms?: ItalyLegalForm[];
};
spain?: {
cifNifs?: string[];
cnae?: string[];
legalForms?: SpainLegalForm[];
};
sectors?: SectorKey[];
employees?: NumericRange[];
totalRevenue?: NumericRange[];
totalRevenueTrend?: ValueTrend[];
employeesCostTrend?: ValueTrend[];
positionCountTrend?: ValueTrend[];
companyStatuses?: CompanyStatus[];
createdAt?: NumericRange[];
};
type V2CompaniesRequest = {
page?: number;
pageSize?: number;
company: APICompanyFilter;
notCompany?: APICompanyFilter;
sortType?: SortType;
sortOrder?: SortOrder;
withPositions?: boolean;
};ids filtra únicamente por identificadores de empresa. parentHoldingIDs filtra las empresas cuya sociedad matriz es uno de los identificadores indicados. La misma distinción se aplica a los filtros company y notCompany en las búsquedas de vacantes.
Ejemplo de cuerpo (JSON)
{
"page": 0,
"company": {
"locations": [
{
"country": "italy",
"levels": [{ "level": 4, "value": "Lombardia" }]
},
{
"country": "spain",
"levels": [{ "level": 4, "value": "Cataluña" }]
}
],
"sectors": ["technologyScienceData"],
"employees": [{ "min": 11, "max": 200 }]
},
"sortType": "name",
"sortOrder": "asc",
"withPositions": true
}El parámetro `withPositions: true` hace que el endpoint devuelva únicamente las empresas con vacantes abiertas.
Respuesta 200
type V2CompanySearchResult = {
companyIDs: string[];
totalPages: number;
totalResults: number;
};totalPages es el número de páginas disponibles para los filtros actuales, con el pageSize solicitado.
Posibles errores
POST /companies/enrich
💳 1 crédito por empresa · 2 créditos con datos financierosEnriquece los datos de empresa a partir de los IDs proporcionados.
Solicitud
type V2CompanyEnrichRequest = {
companyIDs: string[];
};Respuesta 200
type V2EnrichedCompany = {
companyID: string;
parentHolding?: string;
name: string;
workAgency: boolean;
openPositionCount: number;
url?: string;
imageFile?: string;
linkedInURL?: string;
indeedURL?: string;
infoJobsURL?: string;
address?: string;
location?: LocationLevel[];
nation?: string;
sectors: SectorKey[];
employees: YearlyValue[];
totalRevenue: YearlyValue[];
employeesCost: YearlyValue[];
netProfit: YearlyValue[];
italy?: {
ragioneSociale: string;
iva?: string;
ateco?: string;
atecoCode?: string;
rea?: string;
shareCapital?: number;
legalForm?: ItalyLegalForm;
chamberOfCommerce?: string;
};
spain?: {
razonSocial: string;
cifNif?: string;
cnae?: string;
cnaeCode?: string;
legalForm?: SpainLegalForm;
shareCapital?: number;
};
createdAt?: number;
validationKey: string;
};
type V2CompanyEnrichResult = {
companies: V2EnrichedCompany[];
notFoundCompanyIDs: string[];
insufficientCreditsCompanyIDs: string[];
};imageFile contiene solo el nombre del archivo. Para acceder al logotipo, usa la CDN: https://cdn.vocations.io/logos/<imageFile>
notFoundCompanyIDs enumera los identificadores que no existen o no son visibles para tu clave. insufficientCreditsCompanyIDs enumera las empresas existentes omitidas porque los créditos se agotaron durante el lote: vuelve a solicitarlas cuando tengas créditos. Solo se devuelve un 402 cuando no había créditos suficientes para ninguna de las empresas solicitadas.
Posibles errores
POST /companies/status
✓ No consume créditosComprueba si los datos que ya tienes siguen vigentes. Envía cada companyID junto con la validationKey devuelta por /companies/enrich.
Solicitud
type V2CompanyStatusRequest = {
companies: {
companyID: string;
validationKey: string;
}[];
};Ejemplo de cuerpo (JSON)
{
"companies": [
{
"companyID": "cmp1a2b3c4d5e6f7g",
"validationKey": "eyJhbGciOiJIUzI1NiJ9..."
},
{
"companyID": "cmp8h9i0j1k2l3m4n",
"validationKey": "eyJhbGciOiJIUzI1NiJ9..."
}
]
}Respuesta 200
type V2CompanyStatusResult = {
upToDateIDs: string[];
outdatedIDs: string[];
invalidIDs: string[];
};outdatedIDs contiene las empresas cuyos datos han cambiado desde que se emitió tu validationKey: vuelve a enriquecerlas. invalidIDs contiene empresas desconocidas, o claves que no pertenecen al companyID con el que se enviaron.
Posibles errores
Vacantes
POST /positions
💳 3 créditos si hay resultadosSolicitud
type APIPositionFilter = {
ids?: string[];
sources?: PositionSource[];
names?: string[];
cities?: string[];
provinces?: string[];
regions?: string[];
nations?: string[];
languages?: string[];
targets?: string[];
smartWorking?: SmartWorking[];
collar?: (Collar | null)[];
hours?: (Hours | null)[];
contract?: (Contract | null)[];
experience?: (ExperienceLevel | null)[];
protectedCategories?: (boolean | null)[];
skills?: string[];
benefits?: string[];
certifications?: string[];
courses?: string[];
businessUnits?: BusinessUnit[];
yearlySalary?: NumericRange[];
createdAt?: NumericRange[];
};
type V2PositionsRequest = {
page?: number;
pageSize?: number;
position?: APIPositionFilter;
notPosition?: APIPositionFilter;
company?: APICompanyFilter;
notCompany?: APICompanyFilter;
includeNoMatch?: boolean;
};Ejemplo de cuerpo (JSON)
{
"page": 0,
"position": {
"sources": ["vocations", "linkedIn"],
"regions": ["Lombardia"],
"contract": ["permanent"],
"experience": ["1-3", "3-5"]
},
"company": {
"sectors": ["technologyScienceData"]
}
}includeNoMatch: true también incluye vacantes sin empresa asociada.
Respuesta 200
type V2PositionSearchResult = {
positionIDs: string[];
totalPages: number;
totalResults: number;
};Posibles errores
POST /positions/enrich
💳 1 crédito por cada 5 posicionesSolicitud
type V2PositionEnrichRequest = {
positionIDs: string[];
};Respuesta 200
type V2PositionCompanyContext = {
companyID: string;
workAgency: boolean;
italy?: { ragioneSociale: string; iva?: string };
spain?: { razonSocial: string; cifNif?: string };
};
type V2EnrichedPosition = {
positionID: string;
companyContext: V2PositionCompanyContext;
name: string;
description: string;
urls: string[];
sources: PositionSource[];
targets: string[];
cities: string[];
provinces: string[];
regions: string[];
sites: Location[];
skills: string[];
benefits: string[];
languages: string[];
certifications: string[];
courses: string[];
experience?: ExperienceLevel;
contract?: Contract;
hours?: Hours;
smartWorking: SmartWorking;
collar?: Collar;
protectedCategories?: boolean;
yearlySalaryRange?: YearlySalaryRange;
createdAt: number;
republishedAt?: number;
companyName?: string;
validationKey: string;
};
type V2PositionEnrichResult = {
positions: V2EnrichedPosition[];
failedPositionIDs: string[];
};Para obtener todos los datos de la empresa, utiliza el endpoint /companies/enrich.
Posibles errores
POST /positions/check
✓ No consume créditosDevuelve el estado de una o varias vacantes.
Solicitud
type V2PositionsCheckRequest = {
positionIDs: string[];
};Respuesta 200
type V2PositionCheckResult = {
openIDs: string[];
closedIDs: string[];
invalidIDs: string[];
};Posibles errores
Contactos
POST /contacts
✓ No consume créditosBusca los contactos vinculados a una empresa.
Solicitud
type V2ContactsRequest = {
companyID: string;
jobTitles?: string[];
page?: number;
};Respuesta 200
type V2ContactSearchItem = {
contactID: string;
firstName?: string;
lastName?: string;
jobTitle?: string;
hasEmail: boolean;
hasCity: boolean;
};
type V2ContactSearchResult = {
contacts: V2ContactSearchItem[];
totalPages: number;
totalResults: number;
};Posibles errores
POST /contacts/enrich
💳 3 créditos · +2 créditos con número de teléfonoSolicitud
type V2ContactEnrichRequest = {
contactID: string;
enrichPhoneNumber?: boolean;
};Respuesta 200
type V2EnrichedContact = {
contactID: string;
firstName?: string;
lastName?: string;
jobTitle?: string;
headline?: string;
linkedInURL?: string;
photoURL?: string;
departments: string[];
email?: string;
emailStatus?: PendingStatus;
mobilePhone?: string;
phoneStatus?: PendingStatus;
location: LocationLevel[];
validationKey: string;
};Posibles errores
POST /contacts/poll
💳 2 créditos cuando llega un númeroDevuelve el estado actual de un contacto ya enriquecido. Úsalo cuando enrichPhoneNumber haya devuelto phoneStatus: "pending": la obtención del número es asíncrona y llega aquí una vez resuelta.
Solicitud
type V2ContactPollRequest = {
contactID: string;
};Respuesta 200
type V2ContactPollResult = {
email?: string;
emailStatus?: PendingStatus;
mobilePhone?: string;
phoneStatus: PendingStatus;
};Los 2 créditos del teléfono se cobran solo cuando se devuelve un número. Una búsqueda que termina en notAvailable o failed no cuesta nada.
Posibles errores
Uso
GET /usage
✓ No consume créditosDevuelve el estado actual de uso de la clave de API.
Respuesta 200
type V2UsageSnapshot = {
usedCredits: number;
maxCredits: number;
areCreditsShared: boolean;
lastResetAt: number;
};