Stallion ERPStallion ERP

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.

External HR Integration · v1

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.

Base URL https://{your-host}/stallionapi

Quick startThe order that actually matters — each step depends on the one before it

1

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.

2

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.

3

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.

4

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

POST /api/system/auth/login No token required

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

FieldTypeNotes
CompanyKeystringThe key we issued you. Identifies your company/environment — never share it outside your integration.
Required
UserIDstringThe service account UserID we issued you.
Required
PasswordstringThe service account password.
Required
LogLCIDintResponse language for error text. 1 or 1025 = Arabic; anything else (default 0) = English.
Optional
LogMachinestringFree-text identifier for your calling system, used only for diagnostics.
Optional
Request
{
  "CompanyKey": "7k2m9...",
  "UserID": "Api.Hr",
  "Password": "••••••••",
  "LogLCID": 0
}
Response 200 · success
{
  "success": true,
  "token": "vFDVBN0sueVOBr4Yz...",
  "expiryDate": null
}
Using the token Send it on every other call as 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

StatusMeaningBody shape
200Business success{ success: true, message, ...data }
200Business validation failure (bad input, not authorized by permission flag, etc.){ success: false, message, messages: [...] }
401Missing, malformed, invalid, expired, or revoked token{ message }
Don't conflate the two failure modes A 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.

/genders→ Insert employee
/maritalstatuses→ Insert employee
/nationalities→ Insert employee
/employeeclasses→ Insert employee, salary import
/paymentmethods→ Insert employee
/departments→ Insert employee, salary import
/benefitcodes→ Benefit code import
/deductioncodes→ Deduction code import
POST /api/hr/lookups/{name} Bearer token required

Query parameters

FieldTypeNotes
CompanyKeystringRequired
LogUserIDXintReserved for future use — omit or send 0.
Optional
LogLCIDintLanguage for Description/Description2 where applicable.
Optional
Request
POST /api/hr/lookups/departments
  ?CompanyKey=7k2m9...
  &LogLCID=0

Authorization: Bearer <token>
Response 200 · success
[
  {
    "IDX": 12,
    "ID": "04",
    "Description": "Finance",
    "Description2": "Finance"
  }
]

Insert employee

POST /api/hr/employees/insert Bearer token required

Creates one employee. This is insert-only — calling it twice with the same IntegrationID is rejected, not merged.

Request body

FieldTypeNotes
CompanyKeystringRequired
IntegrationIDstringYour own unique identifier for this employee. You'll reference it again in salary imports. Must not already exist.
Required
DepartmentIDXintFrom /lookups/departments. An employee without a department can never be matched by the salary import endpoints.
Required
EmployeeName1stringFirst name segment (max 50 chars).
Required
EmployeeName2 – 4stringAdditional name segments, combined into the employee's full name.
Optional
EmployeeIDstringInternal StallionERP employee code. Leave blank to auto-generate.
Optional
NationalNumberstringNational ID / civil number, stored as given, no format check.
Optional
GenderIDXintFrom /lookups/genders.
Optional
MaritalStatusIDXintFrom /lookups/maritalstatuses.
Optional
NationalityIDXintFrom /lookups/nationalities.
Optional
EmployeeClassIDXintFrom /lookups/employeeclasses. Determines which numbering series generates the employee's code.
Required
PayrollPaymentMethodIDXintFrom /lookups/paymentmethods — only payroll-enabled methods are returned there.
Optional
Request
{
  "CompanyKey": "7k2m9...",
  "IntegrationID": "EXT-4471",
  "DepartmentIDX": 12,
  "EmployeeName1": "Salma",
  "EmployeeName2": "Fadi",
  "EmployeeName3": "Al-Hindawi",
  "GenderIDX": 2,
  "EmployeeClassIDX": 4,
  "PayrollPaymentMethodIDX": 1087
}
Response 200 · success
{
  "success": true,
  "message": "Employee inserted
    successfully.",
  "employeeIDX": 1142,
  "employeeID": "02.0095"
}
Response 200 · multiple validation problems
{
  "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

How the calculation batch is found You never pass a calculation ID. Each call resolves — or creates — the target calculation by Department + Period + EmployeeClass. Send an exact PeriodStartDate/PeriodEndDate pair matching a real payroll period; omit EmployeeClassIDX (or send 0) to match any class.
Each call fully replaces that calculation's lines This is not additive. If you import employee A today and employee B tomorrow for the same period, only B's lines will remain — A's are gone. To keep both, include both employees' rows in the same call.
POST /api/hr/salarycalculation/benefitcodes/import Bearer token required

Request body

FieldTypeNotes
CompanyKeystringRequired
DepartmentIDXintFrom /lookups/departments.
Required
EmployeeClassIDXintFrom /lookups/employeeclasses. Omit or send 0 to target "any class".
Optional
PeriodStartDatedateYYYY-MM-DD, must exactly match an open payroll period.
Required
PeriodEndDatedateYYYY-MM-DD, must exactly match the same period.
Required
BenefitCodesarrayAt least one row. See below.
Required

BenefitCodes[] row

FieldTypeNotes
EmployeeCodestringThe employee's IntegrationID from the insert call. Must belong to the given department (and class, if given).
Required
BenefitCodestringA benefit code's ID/IntegrationID from /lookups/benefitcodes.
Required
AmountdecimalEither this or EmployerContributionValue must be greater than zero.
Optional
EmployerContributionValuedecimalEmployer-paid portion, if applicable.
Optional
Request
{
  "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
    }
  ]
}
Response 200 · success
{
  "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

POST /api/hr/salarycalculation/deductioncodes/import Bearer token required

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

FieldTypeNotes
EmployeeCodestringThe employee's IntegrationID.
Required
DeductionCodestringFrom /lookups/deductioncodes.
Required
AmountdecimalEither this or EmployerContributionValue must be greater than zero.
Optional
EmployerContributionValuedecimalOptional
Request
{
  "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
    }
  ]
}
Response 200 · success
{
  "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.