Skip to main content

Create an HRIS API compatible with Reflect

A guide to building a secure, high-performance, and auditable REST API that enables the transmission of HR data to Reflect.

Written by Reflect Team

šŸ’” This guide is intended for software vendors with their own HR database (HRIS, payroll tool, in-house hub…) and wishing to expose an API compatible with our standards.
​
Reflect will create a connector to a REST API if and only if it is "reusable" for multiple Reflect client companies.

Objective and General Principle

Reflect allows automatic aggregation of HR data from any software (HRIS, payroll, ATS…) via a REST API. The API must allow:

  • Retrieve all structured HR history

  • Automate daily data retrieval

  • Ensure performance, security and reliability

Expected Data

Reflect uses HR data according to a standard semantic model. Each API entry point corresponds to a specific business object.

Here are the 7 business objects your API must expose if you want full coverage:

Business object

Expected data

employee

Demographic and identification information

contract

Contractual information (type, dates, FTE, etc.)

career

Organizational positioning (department, role, site, grade…)

management

Hierarchical reporting link to manager

salary

Theoretical contractual compensation

absence

Days of absence and associated typology

payroll

Actual compensation from the pay slip

Each record must contain a unique and stable employee_id and contract_id, and an effective_date.

Historical vs. Permanent Mode

Your API must support two modes of use:

1. Initial historical load

  • Expose all available HR data from the past 3 years (or more if possible)

  • Support pagination for large volumes (up to 1M+ rows)

  • Allow replaying an export for a specific period (via start_date and end_date)

  • All records must include :

    • a field effective_date (business effective date)

    • a field updated_at (last technical modification date)

2. Permanent Mode (incremental)

  • All endpoints must support the updated_after filter

  • This filter applies to the updated_at field, not effective_date

  • It allows retrieving only the records modified since the last synchronization

šŸ’” An object whose effective_date is old but whose data has been modified must reappear in updated_after calls.

Technical specifications

Authentication

We recommend one of the following two modes:

  • Bearer token in the HTTP header

Authorization: Bearer YOUR_API_TOKEN
  • The token must be able to be manually regenerated if expired.

Response format

  • Strictly structured JSON format

  • List of homogeneous objects

  • Each object contains a employee_id field required and an effective_date field

  • Example :

[
{
"employee_id": "E1234",
"legal_entity": "SAS ABC",
"effective_date": "2023-01-01",
"job_title": "Sales Manager",
"employment_type": "CDI",
"fte": 1.0,
"arrival_date": "2022-03-08",
"contract_start_date": "2023-01-01",
"contract_end_date": null,
"remote_status": "HYBRID"
"employment_type": "CDI",
},
...
]

Pagination

  • Required beyond 500 results

  • Standard: limit + page

  • Recommended: totalCount + links.prev / links.next

  • Example :

GET /contracts?limit=100&page=3

Error handling

Your API must return standardized errors with a readable message in JSON format:

  • All 4xx and 5xx errors must contain an explicit JSON object

  • Always include status, title and errors

Example (HTTP 400)

{
"title": "Validation failed",
"status": 400,
"errors": {
"employee_id": ["This field is required."],
"contract_start_date": ["Invalid format."]
}
}

Business specifications

Required fields

Each field must comply with the business definitions of the Reflect model (cf. details of recommended fields / columns). However, names do not necessarily have to follow Reflect's nomenclature.

You can also include additional data not covered by the document above.

Filtering

All endpoints must allow filtering the data to optimize calls.

Parameter

Target

Type

Example

employee_id

Employee identifier

equality

employee_id=E123

status (optionnel)

HR status (active, inactive)

equality

status=active

start_date / end_date

Range on effective_date

interval

start_date=2024-01-01&end_date=2024-12-31

updated_after

Last modification

ISO date-time

updated_after=2024-07-01T00:00:00Z

Recommendations :

  • The updated_at field is required on each object

  • Use ISO 8601 format for dates (YYYY-MM-DD or YYYY-MM-DDTHH:MM:SSZ)

  • Date ranges can be open (e.g.: start_date=2023-01-01 alone)

Anti-patterns to avoid

Here are common practices that make an API incompatible with Reflect. They must be strictly avoided.

What to avoid

Why it's blocking

API without updated_at field

Impossible to detect changes

Data limited to the ā€œcurrentā€ state

No historical visibility

Physical deletion of records

Breaks data traceability

Unstable model (fields renamed or removed)

Breaks Reflect mappings

Non-persistent HR identifiers (name, email…)

Impossible to track an employee over time

Non-ISO date formats

Parsing impossible or imprecise

Partial data depending on status or implicit filter

Business inconsistencies in dashboards

Recommended documentation

We recommend providing:

  • A link to public documentation (e.g., Swagger) or PDF

  • An example request per object

  • The authentication method and usable parameters (pagination, filters...)

If you're looking for inspiration, the API documentation of Lucca software is of good quality: šŸ“˜ Lucca API Documentation (example to follow)

Integration and creation of the Reflect connector

Once the API is available, our Data team follows this process to create the API connector:

  1. Technical audit (structure, authentication, coverage, volume)

  2. Field quality control (formats, identifiers, coverage)

  3. Mapping with our semantic model

  4. Launch of the automatic flow (production)

The full test generally takes one week if the API is well structured.

Best practices

  • Use a stable HR identifier per employee (employee_id)

  • Expose dates in ISO format (YYYY-MM-DD)

  • Never return empty or ambiguous fields

  • Maintain structural consistency between calls

  • Provide a response time < 5s for 1000 results

Need help? Contact your usual Reflect contact or send us an email at [email protected]. We will be happy to collaborate to set up a stable, reliable and sustainable API.

Did this answer your question?