Support / HR Integration
Technical reference for StallionAPI so an external HR or payroll system can insert employees and salary codes into Stallion ERP. Company: Nawafeth for Electronics Technology. Implemented by WinTech. Mobile app: StallionGo.
HR Integration Reference
Endpoints for an external HR or payroll system to insert employees into StallionERP and push benefit/deduction values into a salary calculation, without touching anything else in the company database.
https://{your-host}/stallionapi
Quick startThe order that actually matters — each step depends on the one before it
Log in once to get a token
Call POST /api/system/auth/login with the CompanyKey, UserID and Password we issued you. Store the returned token — you won't see it again.
Resolve reference values
Call the lookup endpoints (department, employee class, gender, benefit codes, …) to get the IDX values you'll need — these are specific to your company and won't match another one.
Insert the employee
Call POST /api/hr/employees/insert with your own IntegrationID for the employee — you'll reuse this value to reference them later.
Import salary codes for a period
Call the benefit/deduction import endpoints for a payroll period, referencing employees by their IntegrationID. The calculation batch is found or created for you automatically.
Authentication
Exchanges your account credentials for a bearer token. Logging in again issues a new token and immediately invalidates the previous one — there is only ever one active token per account, so a leaked token stops working the moment you rotate it.
Request body
| Field | Type | Notes |
|---|---|---|
| CompanyKey | string | The key we issued you. Identifies your company/environment — never share it outside your integration. Required |
| UserID | string | The service account UserID we issued you. Required |
| Password | string | The service account password. Required |
| LogLCID | int | Response language for error text. 1 or 1025 = Arabic; anything else (default 0) = English.Optional |
| LogMachine | string | Free-text identifier for your calling system, used only for diagnostics. Optional |
{
"CompanyKey": "7k2m9...",
"UserID": "Api.Hr",
"Password": "••••••••",
"LogLCID": 0
}
{
"success": true,
"token": "vFDVBN0sueVOBr4Yz...",
"expiryDate": null
}
Authorization: Bearer <token>. expiryDate is null when your account has no fixed expiry; otherwise re-authenticate before that date.
Requests & responses
Every endpoint below except login also requires the Authorization: Bearer header. Your identity and permissions are resolved server-side from that token — you never need to pass a user or company identifier for authorization, only CompanyKey for routing.
Field casing
Request field names are matched case-insensitively (CompanyKey and companyKey both work) — we document them in PascalCase to match the examples. Response fields are always camelCase.
Success vs. validation failure
Both a business success and a business validation failure come back as HTTP 200 — inspect the success field in the body, not the status code. A validation failure can report more than one problem at once (every check runs independently), via a messages array. Authentication problems are the exception — see the next section.
Error reference
| Status | Meaning | Body shape |
|---|---|---|
| 200 | Business success | { success: true, message, ...data } |
| 200 | Business validation failure (bad input, not authorized by permission flag, etc.) | { success: false, message, messages: [...] } |
| 401 | Missing, malformed, invalid, expired, or revoked token | { message } |
401 means fix your authentication (token). A 200 with success:false means your token was fine but the request itself was rejected — read message/messages for why.
Reference lookupsEight endpoints, one identical shape — resolve these before inserting anything
All eight return active records only, shaped as { IDX, ID, Description, Description2 }. Use the IDX value in the endpoints further down. Description2 falls back to Description when a record has no secondary description, so it's always safe to display.
Query parameters
| Field | Type | Notes |
|---|---|---|
| CompanyKey | string | Required |
| LogUserIDX | int | Reserved for future use — omit or send 0.Optional |
| LogLCID | int | Language for Description/Description2 where applicable.Optional |
POST /api/hr/lookups/departments ?CompanyKey=7k2m9... &LogLCID=0 Authorization: Bearer <token>
[
{
"IDX": 12,
"ID": "04",
"Description": "Finance",
"Description2": "Finance"
}
]
Insert employee
Creates one employee. This is insert-only — calling it twice with the same IntegrationID is rejected, not merged.
Request body
| Field | Type | Notes |
|---|---|---|
| CompanyKey | string | Required |
| IntegrationID | string | Your own unique identifier for this employee. You'll reference it again in salary imports. Must not already exist. Required |
| DepartmentIDX | int | From /lookups/departments. An employee without a department can never be matched by the salary import endpoints.Required |
| EmployeeName1 | string | First name segment (max 50 chars). Required |
| EmployeeName2 – 4 | string | Additional name segments, combined into the employee's full name. Optional |
| EmployeeID | string | Internal StallionERP employee code. Leave blank to auto-generate. Optional |
| NationalNumber | string | National ID / civil number, stored as given, no format check. Optional |
| GenderIDX | int | From /lookups/genders.Optional |
| MaritalStatusIDX | int | From /lookups/maritalstatuses.Optional |
| NationalityIDX | int | From /lookups/nationalities.Optional |
| EmployeeClassIDX | int | From /lookups/employeeclasses. Determines which numbering series generates the employee's code.Required |
| PayrollPaymentMethodIDX | int | From /lookups/paymentmethods — only payroll-enabled methods are returned there.Optional |
{
"CompanyKey": "7k2m9...",
"IntegrationID": "EXT-4471",
"DepartmentIDX": 12,
"EmployeeName1": "Salma",
"EmployeeName2": "Fadi",
"EmployeeName3": "Al-Hindawi",
"GenderIDX": 2,
"EmployeeClassIDX": 4,
"PayrollPaymentMethodIDX": 1087
}
{
"success": true,
"message": "Employee inserted
successfully.",
"employeeIDX": 1142,
"employeeID": "02.0095"
}
{
"success": false,
"message": "The supplied Department is invalid. The supplied Gender is invalid.",
"messages": [
"The supplied Department is invalid.",
"The supplied Gender is invalid."
]
}
Salary calculationPush benefit or deduction values into a payroll period's calculation
Department + Period + EmployeeClass. Send an exact PeriodStartDate/PeriodEndDate pair matching a real payroll period; omit EmployeeClassIDX (or send 0) to match any class.
Request body
| Field | Type | Notes |
|---|---|---|
| CompanyKey | string | Required |
| DepartmentIDX | int | From /lookups/departments.Required |
| EmployeeClassIDX | int | From /lookups/employeeclasses. Omit or send 0 to target "any class".Optional |
| PeriodStartDate | date | YYYY-MM-DD, must exactly match an open payroll period.Required |
| PeriodEndDate | date | YYYY-MM-DD, must exactly match the same period.Required |
| BenefitCodes | array | At least one row. See below. Required |
BenefitCodes[] row
| Field | Type | Notes |
|---|---|---|
| EmployeeCode | string | The employee's IntegrationID from the insert call. Must belong to the given department (and class, if given).Required |
| BenefitCode | string | A benefit code's ID/IntegrationID from /lookups/benefitcodes.Required |
| Amount | decimal | Either this or EmployerContributionValue must be greater than zero. Optional |
| EmployerContributionValue | decimal | Employer-paid portion, if applicable. Optional |
{
"CompanyKey": "7k2m9...",
"DepartmentIDX": 12,
"EmployeeClassIDX": 4,
"PeriodStartDate": "2026-09-01",
"PeriodEndDate": "2026-09-30",
"BenefitCodes": [
{
"EmployeeCode": "EXT-4471",
"BenefitCode": "01",
"Amount": 500.00
},
{
"EmployeeCode": "EXT-4502",
"BenefitCode": "01",
"Amount": 350.00
}
]
}
{
"success": true,
"message": "Salary calculation codes
imported successfully.",
"calculationIDX": 155,
"insertedCount": 2
}
A row per employee, in one call — this is also how you'd re-include an employee from a previous import alongside a new one, since each call replaces the calculation's lines entirely (see the callout above).
Import deduction codes
Identical contract to the benefit code import above — same batch-resolution rule, same full-replace behavior — with a DeductionCodes array in place of BenefitCodes.
DeductionCodes[] row
| Field | Type | Notes |
|---|---|---|
| EmployeeCode | string | The employee's IntegrationID.Required |
| DeductionCode | string | From /lookups/deductioncodes.Required |
| Amount | decimal | Either this or EmployerContributionValue must be greater than zero. Optional |
| EmployerContributionValue | decimal | Optional |
{
"CompanyKey": "7k2m9...",
"DepartmentIDX": 12,
"EmployeeClassIDX": 4,
"PeriodStartDate": "2026-09-01",
"PeriodEndDate": "2026-09-30",
"DeductionCodes": [
{
"EmployeeCode": "EXT-4471",
"DeductionCode": "015",
"Amount": 50.00
},
{
"EmployeeCode": "EXT-4502",
"DeductionCode": "015",
"Amount": 35.00
}
]
}
{
"success": true,
"message": "Salary calculation codes
imported successfully.",
"calculationIDX": 155,
"insertedCount": 2
}
StallionAPI HR Integration Reference — for questions about credentials, permissions, or environment URLs, contact your StallionERP integration contact.