Eligibility via REST API

Use the Eligibility Management API to keep your employee roster in sync with Wellhub so onboarding and offboarding stay up to date. The API follows REST conventions and uses JSON for all requests and responses, where the latter follow standard HTTP status codes to distinguish success and error scenarios.

For information about BASE_URL and ACCESS_TOKEN values, see Getting Started with the REST API. For an overview of Eligibility Identifiers and Entity Types, see Entity Types.

Endpoints summary

EndpointDescription
POST /v1/eligibility/jobsEndpoint to create a job.
POST /v1/eligibility/jobs/{job-id}/itemsEndpoint to create job items.
GET /v1/eligibility/jobs/{job-id}/itemsEndpoint to list the job items.
POST /v1/eligibility/jobs/{job-id}/submitEndpoint to submit a job.
GET /v1/eligibility/jobs/{job-id}/statusEndpoint to retrieve the job status.
GET /v1/eligibility/jobs/{job-id}/errorsEndpoint to list the job errors.
GET /v1/employeesEndpoint to list eligibles for a single entity.
GET /v1/companies/{company-tax-id}/employeesEndpoint to list eligibles for multi entities and channel partners.
GET /v1/companiesEndpoint to list entity companies.

Eligibility jobs

Eligibility jobs are used to create, submit, and track batches of eligibility updates.

Create Job

Create a new eligibility job and return a job identifier for subsequent operations.

Curl example

BASH
curl -X POST "{{BASE_URL}}/v1/eligibility/jobs" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}"

Parameters

This endpoint does not define parameters.

Headers

NameRequiredDescription
AuthorizationYesAuthentication token used to authorize requests.

Response codes

CodeDescription
201Created
401Unauthorized
403Forbidden
500Internal Server Error

Example response

201 Created

JSON
{
  "id": "152f4e34-da90-4c9c-9867-9280952a6b68"
}

Create Job Items

These items are employees' operations, which can create, update or delete entries on Wellhub's database.

For multi entities and channel partners: To get more clarity on the company tax IDs within your group, use the list entity companies endpoint.

Curl example

BASH
curl -X POST "{{BASE_URL}}/v1/eligibility/jobs/{{job-id}}/items" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}" \
  -H "Content-Type: application/json" \
  -d '[
    {
      "operation": "CREATE",
      "company_tax_id": "1234567890",
      "employee_id": "E-1029",
      "full_name": "Maria Santos",
      "email": "maria.santos@acme.com",
      "national_id": "12345678901",
      "department": "People",
      "cost_center": "CC-001",
      "office_zip_code": "12345",
      "eligible_to_payroll": true,
      "custom_fields": {
        "location": "Sao Paulo"
      }
    }
  ]'

Parameters

NameInRequiredDescription
job-idPathYesJob ID.

Request Payload Structure

The request body must be an array of job item objects, with maximum size of 500 items per request. Each object in the array represents an employee operation and supports the following fields:

FieldTypeRequiredDescription
operationstringYesThe action to perform: CREATE, UPDATE, or DELETE
company_tax_idstringYesIdentifies to which company an employee belongs
employee_idstringYes*Employee identifier within company's system
full_namestringNoFull name of the employee
emailstringYes*Email address of the employee.
national_idstringYes*National identification registry of the employee
departmentstringNoDepartment where the employee works
cost_centerstringNoCost center associated with the employee
office_zip_codestringNoZIP code of the employee's office location
eligible_to_payrollbooleanNoEmployee is allowed to use paycheck as a payment method
payroll_idstringNoEmployee identifier in company's payroll software
mobile_numberstringYes*Mobile phone number of the employee.
discount_subset_idstringNoIdentifier for the discount group applicable to the employee, when able.
custom_fieldsobjectNoAdditional custom fields as key-value pairs.

*Depending on the Eligibility Identifier defined in the company's contract with Wellhub, some of these fields may turn out to be optional. For example:

ConfigurationRequired fields
Emailemail
Employee IDemployee_id
National IDnational_id
Employee ID and National IDemployee_id and national_id
Mobile Numbermobile_number

All other identifier fields are optional for the configurations above.

For full details on how each identifier configuration works, see Eligibility Identifiers.

Contact your Wellhub integration representative if you are unsure which identifier applies to your contract.

Headers

NameRequiredDescription
AuthorizationYesAuthentication token used to authorize requests.
Content-TypeYesapplication/json.

Response codes

CodeDescription
204No Content
400Bad Request (validation errors; see response body details)
401Unauthorized
403Forbidden
404Not Found
413Content Too Large (request body exceeds 1 MB limit)
500Internal Server Error

Example request — CREATE

JSON
[
  {
    "operation": "CREATE",
    "company_tax_id": "1234567890",
    "employee_id": "E-1029",
    "full_name": "Maria Santos",
    "email": "maria.santos@acme.com",
    "national_id": "12345678901",
    "department": "People",
    "cost_center": "CC-001",
    "office_zip_code": "12345",
    "eligible_to_payroll": true,
    "custom_fields": {
      "location": "Sao Paulo"
    }
  }
]

Example request — UPDATE

JSON
[
  {
    "operation": "UPDATE",
    "company_tax_id": "1234567890",
    "employee_id": "E-1029",
    "full_name": "Maria Santos",
    "email": "maria.santos@acme.com",
    "national_id": "12345678901",
    "department": "Engineering",
    "cost_center": "CC-002",
    "office_zip_code": "12345",
    "eligible_to_payroll": true,
    "payroll_id": "PAY-123",
    "mobile_number": "+5511999999999",
    "discount_subset_id": "1",
    "custom_fields": {
      "location": "Sao Paulo"
    }
  }
]
Note

For UPDATE operations, any omitted field will be set to an empty value (""). To preserve an existing value, always include it explicitly in the request. The exception is eligible_to_payroll: its behavior when omitted depends on whether the company has payroll enabled. If payroll is not enabled, the field always defaults to false. If payroll is enabled, omitting the field preserves the existing value when one is already set, or defaults to true when no value has been set yet.

custom_fields behaves differently: only fields pre-configured by Wellhub for your company will be persisted or updated. To set up or modify your custom fields mapping, contact your Wellhub integration representative.

Example request — DELETE

JSON
[
  {
    "operation": "DELETE",
    "company_tax_id": "1234567890",
    "employee_id": "E-1029"
  }
]
Note

For DELETE operations, only the fields required to identify the employee (based on the eligibility identifier) and company_tax_id are needed. All other fields are ignored.

Example response

400 Bad Request

JSON
{
  "message": "Bad Request",
  "reason": "Bad information provided",
  "errors": [
    {
      "field": "[0].operation",
      "message": "must be one of CREATE, UPDATE, DELETE"
    },
    {
      "field": "[0].company_tax_id",
      "message": "cannot be blank"
    }
  ]
}

List Job Items

List the items already attached to a job. Supports pagination via the cursor query parameter.

Pagination works as follows: when a response includes a non-null cursor field, pass that value as the cursor query parameter in the next request to retrieve the next page. When cursor is null, you have reached the last page. Do not construct or modify cursor values — treat them as opaque tokens.

Curl example

BASH
curl -X GET "{{BASE_URL}}/v1/eligibility/jobs/{{job-id}}/items?cursor={{cursor}}" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}" \
  -H "Content-Type: application/json"

Parameters

NameInRequiredDescription
job-idPathYesJob ID.
cursorQueryNoCursor for pagination.

Headers

NameRequiredDescription
AuthorizationYesAuthentication token used to authorize requests.

Response codes

CodeDescription
200OK
400Bad Request
401Unauthorized
403Forbidden
404Not Found
500Internal Server Error

Example response

200 OK

JSON
{
  "cursor": "next_cursor_token",
  "data": [
    {
      "id": "item_1",
      "job_id": "job_12345",
      "change_number": 1,
      "company_tax_id": "1234567890",
      "cost_center": "CC-001",
      "created_at": "2026-01-20T10:20:30Z",
      "custom_fields": {
        "location": "Sao Paulo"
      },
      "department": "People",
      "discount_subset_id": "1",
      "eligible_to_payroll": true,
      "email": "maria.santos@acme.com",
      "employee_id": "E-1029",
      "full_name": "Maria Santos",
      "mobile_number": "+5511999999999",
      "national_id": "12345678901",
      "office_zip_code": "12345",
      "operation": "CREATE",
      "payroll_id": "PAY-123"
    }
  ]
}

Submit Job

Submit a job for processing once all items are uploaded.

Curl example

BASH
curl -X POST "{{BASE_URL}}/v1/eligibility/jobs/{{job-id}}/submit" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}"

Parameters

NameInRequiredDescription
job-idPathYesJob ID.

Headers

NameRequiredDescription
AuthorizationYesAuthentication token used to authorize requests.

Response codes

CodeDescription
202Accepted
400Bad Request
401Unauthorized
403Forbidden
404Not Found
409Conflict
422Unprocessable Entity
500Internal Server Error

Example response

No response body is returned for a successful request.

Get Job Status

Get the current processing status for a job.

Curl example

BASH
curl -X GET "{{BASE_URL}}/v1/eligibility/jobs/{{job-id}}/status" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}"

Parameters

NameInRequiredDescription
job-idPathYesJob ID.

Headers

NameRequiredDescription
AuthorizationYesAuthentication token used to authorize requests.

Response codes

CodeDescription
200OK
400Bad Request
401Unauthorized
403Forbidden
404Not Found
500Internal Server Error

Example response

200 OK

JSON
{
  "id": "job_12345",
  "status": "PROCESSING",
  "updated_at": "2026-01-20T10:30:00Z",
  "statistics": {
    "newcomers": 10,
    "updaters": 3,
    "leavers": 2
  }
}

Possible Job Status

Loading diagram...

StatusDescription
DraftJob is in draft state and not yet submitted for validating.
PendingJob is awaiting user action before processing.
ValidatingJob is currently being validated and a change request is in progress; if not rejected, will be processed shortly.
ProcessingJob is currently being processed.
Succeeded with errorsJob has been partially processed, with error entries that must be fixed.
Approval RequestedJob has a pending approval request by either Wellhub or the benefits manager due to extensive breaking changes in the eligible base.
RejectedJob has been rejected.
SucceededJob was processed successfully.
Internal Server ErrorA server-side error occurred during processing. It is recommended to try again.

List Job Errors

List processing errors for a job. Supports pagination via the cursor query parameter.

Curl example

BASH
curl -X GET "{{BASE_URL}}/v1/eligibility/jobs/{{job-id}}/errors?cursor={{cursor}}" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}"

Parameters

NameInRequiredDescription
job-idPathYesJob ID.
cursorQueryNoCursor for pagination.

Headers

NameRequiredDescription
AuthorizationYesAuthentication token used to authorize requests.

Response codes

CodeDescription
200OK
400Bad Request
401Unauthorized
403Forbidden
500Internal Server Error

Example response

200 OK

JSON
{
  "cursor": "next_cursor_token",
  "data": [
    {
      "change_number": 1,
      "field_name": "EMAIL",
      "field_value": "invalid-email",
      "error_type": "WRONG_FORMAT",
      "recovered_by": null,
      "company_tax_id": "1234567890"
    },
    {
      "change_number": 2,
      "field_name": "EMPLOYEE_ID",
      "field_value": "E-1029",
      "error_type": "CONFLICT",
      "recovered_by": null,
      "company_tax_id": "1234567890"
    }
  ]
}

Response fields

FieldTypeDescription
change_numberintegerThe sequential number of the item within the job that caused the error.
field_namestringThe name of the field that triggered the error. See Possible Error Details.
field_valuestringThe value that was submitted for the field.
error_typestringThe type of error. See Possible Error Details.
recovered_bystring or nullIf the error was automatically recovered, indicates the recovery method. null when not recovered.
company_tax_idstringThe company tax ID associated with the item that caused the error.

Possible Error Details

The table below lists all possible field_name and error_type combinations that can be returned in the job errors response.

field_nameerror_typeDescription
COMPANY_TAX_IDINVALID_COMPANY_TAX_IDThe company tax ID does not match any valid company within the entity or group.
EMAILMISSINGThe email field is required based on the eligibility identifier but was not provided.
EMAILWRONG_FORMATThe email address is not in a valid format (expected: name@example.com).
EMAILDUPLICATEDThe same email address appears more than once in the job.
EMAILDOMAIN_UNREACHABLEThe email domain could not be reached or verified.
EMAILNOT_FOUNDThe email does not match any existing eligible record. Applies to UPDATE and DELETE operations.
EMAILCONFLICTThe email conflicts with an existing eligible record that belongs to a different employee.
NATIONAL_IDMISSINGThe national ID field is required based on the eligibility identifier but was not provided.
NATIONAL_IDWRONG_FORMATThe national ID is not in a valid format.
NATIONAL_IDDUPLICATEDThe same national ID appears more than once in the job.
NATIONAL_IDNOT_FOUNDThe national ID does not match any existing eligible record. Applies to UPDATE and DELETE operations.
NATIONAL_IDCONFLICTThe national ID conflicts with an existing eligible record that belongs to a different employee.
EMPLOYEE_IDMISSINGThe employee ID field is required based on the eligibility identifier but was not provided.
EMPLOYEE_IDDUPLICATEDThe same employee ID appears more than once in the job.
EMPLOYEE_IDNOT_FOUNDThe employee ID does not match any existing eligible record. Applies to UPDATE and DELETE operations.
EMPLOYEE_IDCONFLICTThe employee ID conflicts with an existing eligible record that belongs to a different employee.
MOBILE_NUMBERMISSINGThe mobile number field is required based on the eligibility identifier but was not provided.
MOBILE_NUMBERWRONG_FORMATThe mobile number is not in a valid format. Must include the international country code (e.g., +1 999 999 9999).
MOBILE_NUMBERDUPLICATEDThe same mobile number appears more than once in the job.
MOBILE_NUMBERNOT_FOUNDThe mobile number does not match any existing eligible record. Applies to UPDATE and DELETE operations.
MOBILE_NUMBERCONFLICTThe mobile number conflicts with an existing eligible record that belongs to a different employee.
DISCOUNT_SUBSET_IDWRONG_FORMATThe discount subset ID is not in a valid format.

Employees

List Employees

List employees for a single entity. Supports pagination via the cursor query parameter.

Curl example

BASH
curl -X GET "{{BASE_URL}}/v1/employees?cursor={{cursor}}" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}"

Parameters

NameInRequiredDescription
cursorQueryNoCursor for pagination.

Headers

NameRequiredDescription
AuthorizationYesAuthentication token used to authorize requests.

Response codes

CodeDescription
200OK
400Bad Request
401Unauthorized
403Forbidden
500Internal Server Error

Example response

200 OK

JSON
{
  "cursor": "next_cursor_token",
  "data": [
    {
      "id": "emp_456",
      "full_name": "John Doe",
      "email": "john.doe@acme.com",
      "employee_id": "E-2048",
      "national_id": "10987654321",
      "invitation_status": "ACTIVE",
      "mobile_number": "+5511988888888",
      "cost_center": "CC-001",
      "department": "Engineering",
      "office_zip_code": "20040-020",
      "payroll_id": "PAY-2048",
      "discount_subset_id": null,
      "eligible_to_payroll": true,
      "deleted_at": null,
      "updated_at": "2026-01-20T11:00:00Z"
    }
  ]
}

List Company's Employees

List employees for a specific company by tax ID. Supports pagination via the cursor query parameter.

Curl example

BASH
curl -X GET "{{BASE_URL}}/v1/companies/{{company-tax-id}}/employees?cursor={{cursor}}" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}"

Parameters

NameInRequiredDescription
company-tax-idPathYesCompany Tax ID.
cursorQueryNoCursor for pagination.

Note: due to the characteristics of the HTTP protocol, if the company-tax-id has any slash character(s), it must be sent without them.

Example: 00.623.904/0001-73 → 00623904000173 or 00.623.9040001-73

Headers

NameRequiredDescription
AuthorizationYesAuthentication token used to authorize requests.

Response codes

CodeDescription
200OK
400Bad Request
401Unauthorized
403Forbidden
404Not Found
500Internal Server Error

Example response

200 OK

JSON
{
  "cursor": "next_cursor_token",
  "data": [
    {
      "id": "emp_123",
      "full_name": "Maria Santos",
      "email": "maria.santos@acme.com",
      "employee_id": "E-1029",
      "national_id": "12345678901",
      "invitation_status": "INVITED",
      "mobile_number": "+5511999999999",
      "cost_center": "CC-001",
      "department": "People",
      "office_zip_code": "01310-100",
      "payroll_id": "PAY-1029",
      "discount_subset_id": null,
      "eligible_to_payroll": false,
      "deleted_at": null,
      "updated_at": "2026-01-20T10:30:00Z"
    }
  ]
}

Companies

List Entity Companies

If you are managing multiple companies or a channel partner organization, to facilitate eligibility management, you will be able to review the company tax ids under your structure.

List companies for the current entity. Supports pagination via the cursor query parameter.

Curl example

BASH
curl -X GET "{{BASE_URL}}/v1/companies?cursor={{cursor}}" \
  -H "Authorization: Bearer {{ACCESS_TOKEN}}"

Parameters

NameInRequiredDescription
cursorQueryNoCursor for pagination.

Headers

NameRequiredDescription
AuthorizationYesAuthentication token used to authorize requests.

Response codes

CodeDescription
200OK
400Bad Request
401Unauthorized
403Forbidden
500Internal Server Error

Example response

200 OK

JSON
{
  "cursor": "next_cursor_token",
  "data": [
    {
      "company_name": "Cool Company",
      "company_tax_id": "1234567890"
    }
  ]
}