Vacancy Import API v4
This document describes the v4 API for importing and updating job vacancies in Teamio.
Base URL
https://integrations-api.teamio.comEndpoints
Production (requires production credentials):
| Method | Path | Description |
|---|---|---|
POST | /api/import/v4/vacancies | Create a vacancy |
PUT | /api/import/v4/vacancies/{vacancyId} | Update an existing vacancy by ID |
Test (requires test credentials):
| Method | Path | Description |
|---|---|---|
POST | /api/import/test/v4/vacancies | Validate request without persisting data |
PUT | /api/import/test/v4/vacancies/{vacancyId} | Validate update request without persisting data |
Important: Production and test endpoints use separate credentials. The access token obtained from production credentials works only with production endpoints, and the token from test credentials works only with test endpoints. Both sets of credentials are available in Teamio integration settings (login required).
Rate Limiting: Production endpoints enforce a rate limit of 10 requests per minute per company. Test endpoints allow up to 50 requests per minute. Requests exceeding the limit are rejected with HTTP 429.
Vacancy Types
The API supports two distinct vacancy types determined by jobTypeIds:
| Type | jobTypeIds value | Key differences |
|---|---|---|
| Regular vacancy | Any type(s) from EmploymentType list except 201300004 | Multiple job types can be combined; educationLevelId required; salary interval MONTH or YEAR; temporaryWorkTimeSpecification must be absent |
| Temporary work | [201300004] only — cannot be combined with other types | educationLevelId not applicable; temporaryWorkTimeSpecification required; salary interval HOUR, DAY, or ONCE |
Authentication
All requests require a JWT Bearer token obtained from the auth endpoint.
Obtaining a Token
Endpoint: POST /api/v1/auth/token
Note: Both production and test credentials are available in your Teamio integration settings (login required). The password shown there is already Base64-encoded — copy and use it directly. Use production credentials to call production endpoints and test credentials to call test endpoints.
curl --location 'https://integrations-api.teamio.com/api/v1/auth/token' \
--header 'Content-Type: application/json' \
--data '{
"username": "<from Teamio integration settings>",
"password": "<from Teamio integration settings>"
}'Response:
{
"accessToken": "eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...",
"expiresAt": "2026-03-19T15:30:00.000Z",
"tokenType": "Bearer"
}Cache the token and reuse it until expiresAt. Do not request a new token for each API call.
Authentication Flow
Request
Headers:
Authorization: Bearer <accessToken>Content-Type: application/json
The request body is the vacancy object directly at the root — it is not wrapped in a vacancy property. The company identity is derived from the JWT token.
Request Schema
Fields marked with * are required for all vacancy types. Additional rules by type:
- Regular vacancy:
educationLevelIdis also required;temporaryWorkTimeSpecificationmust be absent. - Temporary work (
jobTypeIds=[201300004]):temporaryWorkTimeSpecificationis required;educationLevelIdis not applicable.
Required Fields
| Field | Type | Description | Constraints |
|---|---|---|---|
languageCode | string | Language of the vacancy in ISO 639-1 format | Pattern: ^[a-z]{2}$. Supported: cs, en, de, hr, mk, pl, sk, bs |
name | string | Job title visible to candidates | 5–90 characters |
description | string | Job description; HTML tags allowed | Max 16 383 characters |
educationLevelId | integer | Minimum required education level. Required for regular vacancies only — not applicable for temporary work (jobTypeIds = [201300004]) | 203400001–203400999. Available values |
jobTypeIds | array of integer | Employment type(s) | Min 1 item, 201300001–201300999. Available values . Note: temporary work (201300004) cannot be combined with other types |
industryProfessions | array of object | Industry and profession classification for the vacancy | 1–3 items; max 6 profession IDs in total across all entries. See IndustryProfessions Object. Available values |
locations | array of object | Job location(s) | Min 1 item; each must include countryId |
Optional Fields
| Field | Type | Description | Constraints |
|---|---|---|---|
internalName | string | Internal tracking name, not visible to candidates | |
presentationUnitId | Long | Active presentation unit (org. unit/department). May be required if service is active and mandatory. Available values in Teamio settings (login required) | Must belong to company |
clientId | string | External client identifier for integration tracking. Required if client-id service is active. Available values in Teamio settings (login required) | |
recruitmentProcessTemplateId | string | Custom recruitment process template. Available values in Teamio settings (login required) | Standard: pwf0–pwf4 (always available); custom templates must belong to company |
automaticResponseId | Long | Auto-response email template ID for applicants. Available values in Teamio settings (login required) | Must belong to company and match vacancy language |
recruiterId | Long | ID of the responsible recruiter. Available values in Teamio settings (login required) | Must belong to company; if omitted, derived from footer owner or company default |
headerId | Long | Header template for vacancy presentation. Available values in Teamio settings (login required) | Must belong to company |
footerId | Long | Footer template for vacancy presentation (contact info). Available values in Teamio settings (login required) | Must belong to company; owner can determine recruiter |
externalReplyForm | string | URL of external application form; candidates are redirected here instead of Teamio form | Valid absolute HTTP/HTTPS URL; requires external reply link service |
companyCardId | Long | Company presentation card (profile). Available values in Teamio settings (login required) | |
languageSkills | object | Required language proficiencies | See Language Skills |
jobMarketStatusIds | array of integer | Suitable candidate employment status | 203000001–203000999. Available values |
healthStateId | integer | Health/physical condition requirement | 201900001–201900999. Available values |
disabilityIds | array of integer | Disability suitability indicators | 210000001–210000999 |
salary | object | Salary range information | See Salary Object |
benefitIds | array of integer | Offered employee benefits | 202800001–202800999. Available values |
contractTypeIds | array of integer | Employment contract type(s) | 212700001–212700999. Available values |
employmentDurationId | integer | Expected employment duration | 202700001–202700999. Available values |
jobApplicationFormId | string | Custom job application questionnaire (Flexi form). Available values in Teamio settings (login required) | Requires Flexi services; must belong to company |
customFields | array of object | Company-specific custom field values. Available values in Teamio settings (login required) | See Custom Fields |
temporaryWorkTimeSpecification | object | Work time period for temporary positions | Required when jobTypeIds contains 201300004; must be absent otherwise. See Temporary Work Time Specification |
IndustryProfessions Object
Required. Specifies the professional classification of the vacancy grouped by industry. At least 1 and at most 3 entries are allowed. The total number of profession IDs across all entries must not exceed 6. Industry-only entries (without professionIds) are valid. Available values .
| Field | Type | Description | Constraints |
|---|---|---|---|
industryId | integer | Required. Industry identifier | 200900001–200900999 |
professionIds | array of integer | Profession identifiers within the stated industry. Professions must belong to the specified industry | 201100001–201100999 per item; optional — the entry may consist of industryId only |
Location Object
| Field | Type | Description | Constraints |
|---|---|---|---|
countryId | integer | Required. Country identifier | 1–300 |
region | string | Region/province | Max 100 chars. Supported for: CZ (56), PL (196), SK (217), HU (111), RO (201), LV (137), LT (143), MD (163), CS (267), UA (248), EE (75), FI (81), ES (223), FR (82), BG (37), UK (250) |
district | string | District | Max 100 chars. Supported for: CZ, PL, SK, HU, RO, LV, LT, MD, CS, UA, EE, FI, ES, FR |
city | string | City | Max 100 chars. Supported for: CZ, PL, SK, HU, RO, LV, LT, MD, CS, UA, EE, FI, ES, FR |
cityPart | string | Part of city | Max 100 chars. Supported for: CZ, PL, SK |
street | string | Street name | Max 100 chars. Supported for: CZ, PL, SK |
zip | string | ZIP/postal code | Max 16 chars |
number | string | Building number | Max 16 chars. Supported for: CZ, PL, SK |
orientationNumber | string | Orientation/civic number | Max 16 chars. Supported for: CZ, PL, SK |
text | string | Free-form location text | Max 100 chars. Use for countries without structured address support |
Czech address points can be validated at https://vdp.cuzk.gov.cz/vdp/ruian/overeniadresy .
Salary Object
Optional. If the salary object is present, min and max are required.
| Field | Type | Description | Constraints |
|---|---|---|---|
hidden | boolean | Hide salary from candidates | Default: false |
min | number | Required. Minimum salary amount | 1–9 999 999; must be ≤ max |
max | number | Required. Maximum salary amount | 1–9 999 999; must be ≤ 2× min |
currencyId | integer | Currency | 201400001–201400999. Available values |
intervalId | integer | Payment interval | 209800001–209800999. Available values . Temporary work (201300004): only HOUR/DAY/ONCE; regular positions: only MONTH/YEAR |
Language Skills Object
| Field | Type | Description | Constraints |
|---|---|---|---|
logicalOperator | string | How requirements are combined | AND (all required) or OR (at least one) |
languageProficiencies | array of object | Required language proficiencies | Max 3 items |
Language Proficiency:
| Field | Type | Description | Constraints |
|---|---|---|---|
languageCode | string | Required. Language in ISO 639-1 format | Pattern: ^[a-z]{2}$ |
levelId | integer | Required. Required proficiency level | 201500001–201500999. Available values |
Temporary Work Time Specification
Required only when jobTypeIds contains temporary work (201300004). Temporary work cannot be combined with other job types.
Provide either a continuous date range (from + to) or a list of specific days (exactDays) — not both.
| Field | Type | Description | Constraints |
|---|---|---|---|
from | string | Start date of work period | Format: yyyy-MM-dd; must be ≤ to; use with to only |
to | string | End date of work period | Format: yyyy-MM-dd; must be ≥ from; use with from only |
exactDays | array of string | Specific non-continuous working days | Format: yyyy-MM-dd each; cannot be combined with from/to |
Custom Fields
| Field | Type | Description |
|---|---|---|
key | string | Required. Custom field key/identifier (UUID) as configured for the company. Available values in Teamio settings (login required) |
values | array of string | Required. List of values (UUIDs) for this custom field. Multiple values supported for multi-select fields. Available values in Teamio settings (login required) |
Request Examples
Minimal — Required Fields Only
curl --location 'https://integrations-api.teamio.com/api/import/v4/vacancies' \
--header 'Authorization: Bearer <accessToken>' \
--header 'Content-Type: application/json' \
--data '{
"languageCode": "cs",
"name": "Java Developer",
"description": "Job description with HTML <strong>element</strong>.",
"educationLevelId": 203400005,
"jobTypeIds": [201300001],
"industryProfessions": [
{
"industryId": 200900013,
"professionIds": [201100583]
}
],
"locations": [
{
"countryId": 56,
"city": "Praha"
}
]
}'Typical — Common Fields
curl --location 'https://integrations-api.teamio.com/api/import/v4/vacancies' \
--header 'Authorization: Bearer <accessToken>' \
--header 'Content-Type: application/json' \
--data '{
"languageCode": "cs",
"name": "Senior Java Developer",
"description": "We are looking for an experienced Java developer. <strong>Requirements:</strong><ul><li>5+ years of Java experience</li><li>Spring Boot knowledge</li></ul>",
"industryProfessions": [
{
"industryId": 200900013,
"professionIds": [201100050]
}
],
"educationLevelId": 203400005,
"jobTypeIds": [201300001],
"contractTypeIds": [212700001],
"locations": [
{
"countryId": 56,
"city": "Praha",
"street": "Menclova",
"number": "2538",
"orientationNumber": "2"
}
],
"salary": {
"min": 60000,
"max": 90000,
"currencyId": 201400001,
"intervalId": 209800002
},
"benefitIds": [202800005, 202800010],
"languageSkills": {
"logicalOperator": "AND",
"languageProficiencies": [
{"languageCode": "cs", "levelId": 201500005},
{"languageCode": "en", "levelId": 201500004}
]
}
}'Maximum — All Fields
Values for
presentationUnitId,automaticResponseId,recruiterId,headerId,footerId,companyCardId,jobApplicationFormId, andcustomFieldsare company-specific. Retrieve them from Teamio integration settings (login required).
curl --location 'https://integrations-api.teamio.com/api/import/v4/vacancies' \
--header 'Authorization: Bearer <accessToken>' \
--header 'Content-Type: application/json' \
--data '{
"languageCode": "cs",
"name": "Senior Java Developer",
"internalName": "Java-TEAM-A-2025-Q1",
"description": "Full job description with HTML <strong>formatting</strong>.",
"industryProfessions": [
{
"industryId": 200900013,
"professionIds": [201100050, 201100102]
},
{
"industryId": 200900030
}
],
"educationLevelId": 203400005,
"jobTypeIds": [201300001],
"contractTypeIds": [212700001],
"employmentDurationId": 202700001,
"jobMarketStatusIds": [203000001, 203000002],
"healthStateId": 201900001,
"disabilityIds": [210000001],
"locations": [
{
"countryId": 56,
"region": "Hlavní město Praha",
"district": "Praha 10",
"city": "Praha",
"cityPart": "Strašnice",
"street": "V olšinách",
"number": "2300",
"orientationNumber": "75",
"zip": "10000"
},
{
"countryId": 111,
"city": "Gárdony"
}
],
"salary": {
"hidden": false,
"min": 60000,
"max": 90000,
"currencyId": 201400001,
"intervalId": 209800002
},
"benefitIds": [202800005, 202800010],
"languageSkills": {
"logicalOperator": "AND",
"languageProficiencies": [
{"languageCode": "cs", "levelId": 201500005},
{"languageCode": "en", "levelId": 201500004}
]
},
"presentationUnitId": 67890,
"clientId": "CLIENT-2025-001",
"recruitmentProcessTemplateId": "pwf2",
"automaticResponseId": 12345,
"recruiterId": 54321,
"headerId": 11111,
"footerId": 22222,
"companyCardId": 98765,
"externalReplyForm": "https://example.com/apply/job123",
"jobApplicationFormId": "flexi-form-123",
"customFields": [
{"key": "86780993-8b74-46df-9f88-468205463f25", "values": ["a6865239-16a3-49d6-b92f-b4130089e5c5", "f95610ec-2531-4835-8167-331215b4f05c"]}
]
}'Temporary Work Example
Temporary work (201300004) must be the only job type and requires temporaryWorkTimeSpecification.
curl --location 'https://integrations-api.teamio.com/api/import/v4/vacancies' \
--header 'Authorization: Bearer <accessToken>' \
--header 'Content-Type: application/json' \
--data '{
"languageCode": "cs",
"name": "Warehouse Worker (Temporary)",
"description": "Temporary warehouse position.",
"jobTypeIds": [201300004],
"industryProfessions": [
{
"industryId": 200900020
}
],
"locations": [
{
"countryId": 56,
"city": "Brno"
}
],
"salary": {
"min": 150,
"max": 200,
"currencyId": 201400001,
"intervalId": 209800004
},
"temporaryWorkTimeSpecification": {
"from": "2025-07-01",
"to": "2025-07-31"
}
}'Alternatively, specify exact working days:
"temporaryWorkTimeSpecification": {
"exactDays": ["2025-07-07", "2025-07-14", "2025-07-21", "2025-07-28"]
}Update Existing Vacancy
Use PUT with the Teamio vacancy ID to update an existing vacancy. The request body follows the same schema as creation — this is a full-replacement operation, meaning that all fields on the vacancy are replaced with the values provided in the request body.
Behavior of omitted fields on update
PUT is not a partial update. Any fields (including optional ones) that are omitted from the request body are treated as cleared on the vacancy (set to null / default / empty as applicable). To keep existing values for a field, you must include that field with its current value in the PUT payload.
Update-specific constraints:
- The vacancy must exist; otherwise HTTP
404is returned. - Vacancies with status
DELETEDorARCHIVEDcannot be updated; HTTP422is returned. - Switching between temporary work (
jobTypeIds=[201300004]) and non-temporary work is not allowed in a single update; HTTP422is returned. To change the type, delete and recreate the vacancy. - If the vacancy has status
PUBLISHED, it is automatically republished to the advert platform after a successful update. - Because PUT is full replacement, clients that want to preserve all existing values should send the full vacancy payload, including unchanged fields.
Warning
PUT requests are destructive for omitted fields. Any field present on the existing vacancy but missing from the request body will be cleared. Do not send a partial payload unless you explicitly intend to remove all omitted data.
Example update (full replacement semantics):
In the following example, the vacancy is updated with a subset of fields. All other fields previously set on the vacancy (for example, salary or benefits, if they existed) will be cleared because they are not included in the payload.
curl --location --request PUT \
'https://integrations-api.teamio.com/api/import/v4/vacancies/123456' \
--header 'Authorization: Bearer <accessToken>' \
--header 'Content-Type: application/json' \
--data '{
"languageCode": "cs",
"name": "Senior Java Developer (Updated)",
"description": "Updated job description.",
"educationLevelId": 203400005,
"jobTypeIds": [201300001],
"industryProfessions": [
{
"industryId": 200900013,
"professionIds": [201100050]
}
],
"locations": [
{
"countryId": 56,
"city": "Praha"
}
]
}'Response
HTTP Status: 200 OK when the import service processes the request — including business-level failures such as validation errors. The status field in the response body indicates the outcome.
Non-200 HTTP status codes are returned for infrastructure-level errors (e.g. malformed JSON, authentication failure). In those cases the response body uses a different format — see Error Responses.
Response Fields
| Field | Type | Description |
|---|---|---|
status | string | Overall import result (see Status Values below) |
vacancyId | Long | Teamio vacancy ID. Set when status is OK. null when status is ERROR. In create test mode always 0. In update test mode reflects the vacancy ID from the URL path. |
messages | array | List of informational, warning, and error messages |
processedAt | string | ISO 8601 timestamp of when the request was processed |
Status Values
| Status | Description |
|---|---|
OK | Vacancy successfully imported/updated; check messages for any warnings |
ERROR | Validation failed; vacancy not created or updated |
UNPROCESSABLE | Request is valid but violates business rules |
BAD_REQUEST | Invalid request format or missing required fields |
SERVICE_NOT_ACTIVE | Import service not enabled for this company |
UNAUTHORIZED | Authentication failed |
METHOD_NOT_ALLOWED | HTTP method not allowed for this endpoint |
UNKNOWN_ERROR | Unexpected server error |
Message Types
Each item in messages has a type field:
| Type | Description |
|---|---|
OK | Success confirmation |
INFO | Informational note |
WARNING | Non-critical issue; vacancy was imported but attention recommended |
ERROR | Critical validation failure |
Success Response
{
"status": "OK",
"vacancyId": 123456,
"messages": [],
"processedAt": "2026-03-19T14:30:00.000Z"
}Success with Warnings
Status is OK even when warnings are present — always check messages for WARNING-type entries.
{
"status": "OK",
"vacancyId": 123457,
"messages": [
{
"type": "WARNING",
"message": "Presentation unit not provided but service is active for company"
}
],
"processedAt": "2026-03-19T14:30:00.000Z"
}Validation Error Response
{
"status": "ERROR",
"vacancyId": null,
"messages": [
{
"type": "ERROR",
"message": "Name is required."
},
{
"type": "ERROR",
"message": "EducationLevelId is required."
}
],
"processedAt": "2026-03-19T14:30:00.000Z"
}Test Mode Response
Create (POST /api/import/test/v4/vacancies): vacancyId is always 0 — no real vacancy is created:
Update (PUT /api/import/test/v4/vacancies/{vacancyId}): vacancyId reflects the ID from the URL — no changes are persisted and no republication is triggered:
{
"status": "OK",
"vacancyId": 0,
"messages": [],
"processedAt": "2026-03-19T14:30:00.000Z"
}Error Responses
When a non-200 HTTP status is returned, the response body follows the RFC 7807 Problem Details format instead of the normal import response format.
HTTP 400 — Bad Request
Returned when the request body is missing or cannot be parsed:
{
"title": "Bad Request",
"status": 400,
"detail": "Bad request.",
"instance": "/api/import/v4/vacancies",
"messages": [
{
"type": "ERROR",
"message": "Request body is missing or malformed."
}
]
}Returned when the upstream import service rejects the request (e.g. business rule violation, inactive service):
{
"title": "Bad Request",
"status": 400,
"detail": "Validation error occurred. Please check the error messages for details and correct the request accordingly.",
"instance": "/api/import/v4/vacancies",
"messages": [
{
"type": "ERROR",
"message": "Company does not have active import service."
}
]
}HTTP 401 — Unauthorized
Returned by the authentication layer when the Bearer token is missing or invalid. No body is guaranteed.
HTTP 403 — Forbidden
Returned by the authorization layer when the token does not have the required permissions. No body is guaranteed.
HTTP 404 — Not Found (update only)
Returned when the vacancy ID in the URL does not exist:
{
"title": "Not Found",
"status": 404,
"detail": "The requested vacancy was not found.",
"messages": [
{
"type": "ERROR",
"message": "Vacancy with ID 123456 not found."
}
]
}HTTP 422 — Unprocessable Entity (update only)
Returned when the vacancy exists but cannot be updated — either because its status is terminal or an invalid field change is attempted:
{
"title": "Unprocessable Entity",
"status": 422,
"detail": "Validation error occurred. Please check the error messages for details and correct the request accordingly.",
"messages": [
{
"type": "ERROR",
"message": "Vacancy with ID 123456 cannot be updated because it has status ARCHIVED."
}
]
}{
"title": "Unprocessable Entity",
"status": 422,
"detail": "Validation error occurred. Please check the error messages for details and correct the request accordingly.",
"messages": [
{
"type": "ERROR",
"message": "Changing job type between temporary work (jobType = 201300004) and non-temporary work is not allowed."
}
]
}HTTP 429 — Too Many Requests
Returned when the per-company rate limit is exceeded (10 req/min for production endpoints, 50 req/min for test endpoints). The response body follows the standard RFC 7807 Problem Details format used by other API error responses.
{
"title": "Too Many Requests",
"status": 429,
"detail": "You have sent too many requests. Please try again later.",
"instance": "/api/import/v4/vacancies",
"messages": [
{
"type": "ERROR",
"message": "Rate limit exceeded for companyId=12345."
}
]
}Wait until the current minute window resets before retrying. Consider adding retry logic with a back-off to handle this gracefully.
Common Validation Error Messages
| Error message | Cause | Fix |
|---|---|---|
Name is required. | name is missing or blank | Provide a name between 5–90 characters |
Name must be between 5 and 90 characters. | name too short or too long | Adjust length |
Locations are required. | locations is missing or empty | Provide at least one location |
EducationLevelId is required. | educationLevelId is null | Provide a valid education level ID |
JobTypeIds are required. | jobTypeIds is missing or empty | Provide at least one job type ID |
LanguageCode is required. | languageCode is null | Provide a two-character ISO 639-1 code |
IndustryProfessions are required. | industryProfessions is missing or empty | Provide 1–3 industry-profession entries |
IndustryProfessions must contain between 1 and 3 items. | industryProfessions entry count is outside the 1–3 range | Provide between 1 and 3 entries |
Maximum 6 professionIds are allowed in total. | Total profession IDs across all entries exceeds 6 | Reduce profession IDs to 6 or fewer in total |
IndustryId X does not exist. | industryId is not a recognised industry | Use a valid industry ID from the SVL reference |
ProfessionId X does not belong to industryId Y. | Profession ID is not part of the stated industry | Ensure each profession ID belongs to the industry it is listed under |
Min salary is required. | salary.min is null when salary object is present | Provide both min and max |
Min salary must be <= max salary. | min > max | Correct the salary range |
Max salary must be <= 2x min salary. | max > 2× min | Correct the salary range |
Temporary work time specification is required. | Missing for temporary work job type | Provide temporaryWorkTimeSpecification |
TemporaryWorkTimeSpecification must be absent for non-temporary work. | Field present for non-temporary job type | Remove temporaryWorkTimeSpecification |
Presentation unit is mandatory for this company. | Company has mandatory presentation units | Provide a valid presentationUnitId |
Recruiter not found or does not belong to company. | Invalid recruiterId | Use a recruiter ID from your company |
Footer does not belong to company. | Invalid footerId | Use a footer ID from your company |
Automatic response template language does not match vacancy language. | automaticResponseId language mismatch | Use a template matching languageCode |
Vacancy with ID {id} not found. | Update only. Vacancy ID in URL does not exist | Check the vacancy ID; use the ID returned by the create endpoint |
Vacancy with ID {id} cannot be updated because it has status DELETED. | Update only. Vacancy has been deleted | Deleted vacancies cannot be updated; create a new vacancy |
Vacancy with ID {id} cannot be updated because it has status ARCHIVED. | Update only. Vacancy has been archived | Archived vacancies cannot be updated |
Changing job type between temporary work (jobType = 201300004) and non-temporary work is not allowed. | Update only. Attempt to switch between regular and temporary work | To change the type, delete and recreate the vacancy |
Validation Rules Summary
Service-Dependent Fields
Some fields behave differently based on services active for your company:
| Field | Service required | Behavior when service inactive | Behavior when service active |
|---|---|---|---|
presentationUnitId | Presentation units | WARNING if provided | WARNING if omitted; ERROR if value invalid |
clientId | Client ID service | WARNING if provided | ERROR if omitted |
externalReplyForm | External reply link | WARNING if provided (ERROR if invalid URL) | WARNING if omitted |
recruitmentProcessTemplateId | Paid edition | WARNING if provided | WARNING if omitted |
jobApplicationFormId | Flexi services | — | ERROR if form not found or not belonging to company |
Conditional Fields
| Field | Condition |
|---|---|
temporaryWorkTimeSpecification | Required when jobTypeIds = [201300004]; must be absent otherwise |
salary.min + salary.max | Required when salary object is present |
temporaryWorkTimeSpecification.from + to | Must be provided together; mutually exclusive with exactDays |
Testing
Use the test endpoint to validate your payload before production:
curl --location 'https://integrations-api.teamio.com/api/import/test/v4/vacancies' \
--header 'Authorization: Bearer <accessToken>' \
--header 'Content-Type: application/json' \
--data '{ ... same body as production ... }'The response structure is identical to production. On success, vacancyId is always 0 — no real vacancy is created.
Best Practices
- Test before production — always validate with the test endpoint first
- Cache auth tokens — reuse tokens until
expiresAtto avoid unnecessary auth calls - Check all messages —
statusisOKeven when warnings are present; always inspectmessagesforWARNING-type entries - Follow ID ranges — use IDs from the specified ranges; refer to the linked SVL lists
- Use credentials as-is — the password in Teamio integration settings is already Base64-encoded; copy and use it directly
- Keep credentials secure — never log or commit credentials or tokens to version control