How an SAP HR master data upload works
PA30 in SAP maintains an employee's infotypes one record at a time, and PA40 runs personnel actions such as a hire or a transfer. An SAP HR master data upload writes those infotype records from Excel: PostNow.ai sends each row through a recording of PA30 or PA40, or through a remote-enabled function module your SAP team provides around HR_INFOTYPE_OPERATION or SAP's employee BAPIs, because HR_INFOTYPE_OPERATION itself is a normal function module and cannot be called over RFC. Validate checks the sheet offline, Simulate lets SAP check the rows, and Run writes each record under the user's own SAP login and authorizations, with SAP's answer on every row.
- The dates are part of the key. Each infotype record is identified by personnel number, infotype, subtype and validity period, and on time constraints 1 and 2 a new record delimits the one before it.
- The file is personal data. HR authorizations (
P_ORGIN, structural authorizations) apply to every row, and the spreadsheet needs the same care as the system it came from.
This page covers one job: the SAP HR master data upload from Excel, writing infotype records for many employees in one run. Uploads for the other master data objects, and the order to load them in, are in SAP master data mass upload. A full migration of SAP HCM data into a new system is planned as described in SAP master data migration; the HR-specific points are in the SAP HR data migration section below.
How PostNow.ai runs an SAP HR master data upload from Excel
PostNow.ai runs an HR upload as a published template: a designer builds it once against your SAP system for one infotype and one route, and HR administrators run their own files through it, each under their own SAP login, on their own computer, when they click Run.
- Pick the route. Record PA30 for one infotype (or PA40 for an action) in
SHDB, or find your SAP team's remote-enabled HR function module by name in BAPI search; PostNow.ai reads its interface from your system. The posting route section explains which one fits. - One sheet per infotype. Every row carries the record key (personnel number, subtype where the infotype has subtypes, validity begin and end) followed by that infotype's fields. A sheet for addresses (0006) and a sheet for basic pay (0008) share almost no columns, so they are separate templates.
- Set the field rules. Mark the key columns required, give dates one format, and add allow-lists where the values are fixed, such as the subtypes your company uses. Personnel numbers keep their leading zeros as text.
- Validate the sheet. Validate checks every cell offline: required fields, type, length, date format and allowed values. Whether the employee is hired on that date, or whether your authorization covers the employee, is SAP's answer, and that comes in Simulate.
- Simulate. On a function module template, PostNow.ai calls it for every row and then
BAPI_TRANSACTION_ROLLBACKinstead of a commit. On a recording, Simulate walks the PA30 screens without saving. Either way, SAP's messages land on each row and no record is written. - Run. PostNow.ai writes each row (a function module template commits only when SAP returned no error; a recording saves as PA30 does) and writes SAP's message to the Run Log next to the row, with user, time and system.
- Re-run only what failed. Retry Failed re-posts only the rows marked ERROR. If someone clicks Run again on the same sheet, PostNow.ai first lists the rows whose Run Log already shows a success and offers Skip posted rows before anything is sent to SAP.
Where HR wants a second person to check a file before it touches employee records, an approval policy on the template holds the run until an approver has reviewed the rows in the PostNow.ai portal. The approval is tied to that exact data, so a sheet changed after approval needs approval again.
PA30 vs PA40: personnel actions versus individual infotypes
PostNow.ai can replay either transaction, and the choice depends on whether the file records a business event or a correction to one infotype.
| Transaction | What it does | Use it in an upload for |
|---|---|---|
| PA30 Maintain HR master data | Creates, changes, copies, delimits or deletes one infotype record for one employee | Address changes, bank details, communication records, a pay review on 0008, corrections to a single infotype |
| PA40 Personnel actions | Runs an action type (hire, organizational change, leaving) through its info group, the set of infotypes the action needs, and records the action in infotype 0000 | Hires, transfers and leavers, where several infotypes must change together and the action reason is reported on later |
The difference matters for completeness. A transfer usually changes organizational assignment (0001) and may also need a new work schedule (0007) or pay (0008), depending on how the action is configured. Loading only 0001 through PA30 leaves an employee whose records are each valid but who has no action in 0000 to explain the move. Ask HR administration which infotypes the event touches. For life-cycle events, record the PA40 action with its info group; for corrections and periodic refreshes, a PA30 template per infotype is the simpler and safer file.
Positions and organizational units come first
Infotype 0001 points to a position, and the position belongs to an organizational unit in Organizational Management. Both are time-dependent objects of their own. An assignment to a position that does not exist on the record's start date fails with PG 432 "Position … not available for the start date of the infotype record". Before a reorganisation file, confirm the new positions exist from the right date; if they do not, the HR file is the second run, not the first. Cost center and organizational unit are often derived from the position, so a file that also sends them can disagree with what the position implies.
The infotypes you load most
PostNow.ai builds one template per infotype, because each infotype has its own structure (P0006 for addresses, P0008 for basic pay) and its own rules. These are the ones HR teams most often fill from a spreadsheet:
| Infotype | Name | What to get right in the file |
|---|---|---|
0000 | Actions | Written by a PA40 action, not loaded on its own; the action type and reason come from the action |
0001 | Organizational Assignment | Time constraint 1; the position must exist on the start date; changes usually belong to an action |
0002 | Personal Data | Time constraint 1; names, birth date, nationality and, in some country versions, religious denomination: treat every column as sensitive personal data |
0006 | Addresses | Subtype decides the address type (for example permanent or temporary residence), and the time constraint can differ per subtype |
0007 | Planned Working Time | The work schedule rule must exist for the employee's groupings on the start date |
0008 | Basic Pay | Wage types, amounts and pay scale data; a start date in a period payroll has already run triggers retroactive accounting |
0009 | Bank Details | Subtype for main or other bank; IBAN and bank key are personal financial data |
0105 | Communication | Subtype for the communication type, for example the SAP user (0001) or e-mail; one record per subtype |
Infotypes 0014 (recurring payments and deductions) and 0015 (additional payments) follow the same pattern as 0008: wage type, amount, date, and a payroll consequence for every date in the past.
Time constraints 1, 2 and 3: what may coexist
PostNow.ai sends each record as the file states it, and SAP's time constraint then decides what happens to the records already on the employee. SAP Help defines the three constraints this way:
| Constraint | Rule | What a new record does |
|---|---|---|
| 1 | Exactly one valid record for the whole time the employee works at the enterprise, with no overlaps. Gaps are allowed only between the entry date and the first record. | Delimits the previous record at the new start date. Used for personal data and organizational assignment. |
| 2 | At most one valid record at a time; the record is optional, so gaps are allowed. | Delimits the previous record if one exists. |
| 3 | Any number of valid records at the same time. | Adds a record; nothing is delimited. |
Two more indicators matter for uploads. T means the constraint depends on the subtype, which is how an infotype such as 0006 can treat address types differently. A and B allow one record with a fixed validity from 01.01.1800 to 31.12.9999. The constraint per infotype is in table T582A (view V_T582A), and per subtype in T591A; read both for every infotype in the file before you build it.
Delimiting: correct behaviour that a wrong date turns into damage
On constraints 1 and 2, a new record ends the one before it on the day before its own start. That is exactly what an address move or a cost center change on the first of the month needs. In a file, it also means a wrong start date does not fail: it ends a record that should have continued, and SAP saves it as a normal change. Before the run, extract the current records of every employee in the file with the HR reports your team already uses, so that any record ended by mistake can be put back from known values.
Effective dates and operations: create, change, delimit
PostNow.ai maps the operation like any other column, so the file says for each row whether it creates, changes or delimits a record. HR_INFOTYPE_OPERATION uses these operation codes:
INScreates a record from the validity begin date. On constraints 1 and 2 it delimits the record before it, which makes it the normal operation for a change that takes effect on a date.MODchanges a record in place for its existing validity period. The record you pass replaces the stored one, so a change file carries every field of the infotype, read from SAP first, not only the field that changes.LIS9delimits a record at a date without creating a new one. SAP Community threads report that it does not always work through the function module, and the usual alternative isMODwith the new end date; prove whichever you use on one employee first.DELdeletes a record, and with it the history the record held. Few upload files should contain it.
The choice between INS and MOD is a business decision. A pay correction that was always wrong is a MOD of the existing record; a pay increase from 1 April is an INS from that date. A file that uses INS for corrections leaves the wrong value visible in the earlier period. On a PA30 recording the same decision is made by the function you record (Create, Change, Delimit), so a correction file and a new-value file are two templates.
Validity begin and end are part of the key, so set them before any value: 99991231 for an open record, and a begin date on or after the employee's entry date for most infotypes. The parameter descriptions of VALIDITYBEGIN and VALIDITYEND are known to be swapped in SE37, while the types (BEGDA, ENDDA) are right; map by the type.
Posting route: PA30 recording or a remote-enabled wrapper
PostNow.ai posts an HR file through one of two verified routes: a recording of PA30 or PA40, or a remote-enabled function module that your SAP team owns and that PostNow.ai finds by name in BAPI search. Calling HR_INFOTYPE_OPERATION directly is not one of them. In SE37 it is a normal function module of function group HRMM, not a remote-enabled one, so no program outside SAP can call it over RFC; its RECORD parameter is also untyped, while RFC parameters need Dictionary types.
| Route | How it works | Fits |
|---|---|---|
| PostNow.ai + PA30 or PA40 recording | Record one employee in SHDB, map the screen fields to columns, and PostNow.ai replays the recording per row. PA30 locks the employee and runs its own checks, exactly as for a user at the screen. | Any infotype or action you can maintain in PA30 or PA40, with no ABAP development |
| PostNow.ai + remote-enabled wrapper | A customer function module, flagged Remote-Enabled in SE37, that locks the employee, writes the record with HR_INFOTYPE_OPERATION or an employee BAPI, releases the lock and returns SAP's message in RETURN. PostNow.ai maps it like any BAPI. | High-volume or recurring files on infotypes your SAP team has wrapped |
| SAP employee BAPIs called alone | The infotype BAPIs below are remote-enabled, but they expect the personnel number to be locked with BAPI_EMPLOYEE_ENQUEUE in the same SAP session | Inside a wrapper, which holds the lock and the write in one call |
SAP's employee BAPIs and their RFC status
These function modules are delivered by SAP and flagged Remote-Enabled. Each one covers one infotype and takes a typed structure, such as BAPIP0006 for addresses:
| Infotype | Function modules |
|---|---|
| 0002 Personal Data | BAPI_PERSDATA_CREATE, BAPI_PERSDATA_CHANGE |
| 0006 Addresses | BAPI_ADDRESSEMP_CREATE, BAPI_ADDRESSEMP_CHANGE |
| 0008 Basic Pay | BAPI_BASICPAY_CREATE, BAPI_BASICPAY_CHANGE |
| 0009 Bank Details | BAPI_BANKDETAIL_CREATE |
| 0021 Family Member/Dependents | BAPI_FAMILY_CREATE |
| 0105 Communication | BAPI_EMPLCOMM_CREATE |
| Lock and release | BAPI_EMPLOYEE_ENQUEUE, BAPI_EMPLOYEE_DEQUEUE |
| Find employees (read) | BAPI_EMPLOYEE_GETDATA |
Without the lock, these BAPIs answer PG 184 "Employee/applicant is not locked yet". PostNow.ai calls each function module in its own SAP session and closes the connection after the call, so the lock and the write belong together inside one remote-enabled wrapper. That is also why the wrapper is the cleaner design for HR_INFOTYPE_OPERATION: one call per row locks the employee, writes the record and releases the lock, and SAP returns one answer for that row.
What the wrapper needs to get right
- Run under the caller's own user. The wrapper must not switch to another user or call through a destination with a stronger user, so
P_ORGINand structural authorizations are checked for the person who clicked Run. - Leave the commit to the caller. Pass
NOCOMMIT = 'X'toHR_INFOTYPE_OPERATIONor the BAPI. PostNow.ai then commits withBAPI_TRANSACTION_COMMITwhen SAP returned no error, rolls back when it did, and thenBAPI_TRANSACTION_ROLLBACKinstead of a commit in Simulate. Without the flag, the function module commits by itself and Simulate would save the record. - Type every parameter. One Dictionary structure per infotype (for example
P0006) in place of the untypedRECORD, plus the key fields, the operation andRETURN. - Give it a name your team will search for. PostNow.ai finds it with BAPI search by name pattern, for example
Z_HR_INFOTYPE*, and loads its parameters from your system. Give a writing wrapper a name that does not end in a read suffix such as_GET,_READor_FIND: PostNow.ai treats those names as read-only and sends no commit. - Agree when the lock is released. With
NOCOMMIT = 'X'the record is saved at PostNow.ai's commit, after the wrapper has returned, and SAP releases the session's remaining locks when PostNow.ai closes the connection after the call. Your SAP team decides whether the wrapper releases the lock itself or leaves it to the end of the session, and tests both cases. - Test it with your HR and security teams in a test client on one employee per infotype and operation before the first file.
Recording PA30 or PA40 instead
A recording needs no new ABAP from your SAP team: record one employee in SHDB on the infotype (or the action) the file maintains, map the screen fields to columns, and PostNow.ai replays it for every row. The BDC recording guide covers how to record so the replay holds, and BAPI vs BDC in SAP compares the two methods.
- Record each operation separately. Create, Change and Delimit are different functions in PA30, so each gets its own recording and template.
- Recording mode needs PostNow.ai's
ZPOSTNOW_*objects in SAP, installed once per system. The wrapper route needs no PostNow.ai objects: RFC access plus the user's normal HR authorizations. - Simulate on a recording walks the PA30 screens without saving, so SAP's save-time checks arrive at Run. Prove the recording on one employee in Debug before the first full file.
- SAP GUI stays with the user. PostNow.ai logs in to SAP GUI only on the user's own computer, with the user's own stored login, when the user starts the action (Record, Run, Debug or Call Transaction); never on a server, never unattended, never with someone else's login. On the wrapper route, the RFC connection uses the SAP login the user stored for this in PostNow.ai on their own computer, and it is closed after each call.
Authorizations and personal data in an HR upload
PostNow.ai writes every row under the SAP login of the person who runs the file, so SAP's HR authorization checks decide row by row what that person may change; nothing in the run widens them.
| Check | What SAP tests | What it means for the file |
|---|---|---|
P_ORGIN HR: Master Data | Infotype (INFTY), subtype (SUBTY), authorization level (AUTHC), personnel area, employee group, employee subgroup and organizational key, read from the employee's infotype 0001 | The runner needs write access for this infotype and subtype for every employee in the file |
P_PERNR personnel number check | Access to the user's own personnel number, when the AUTSW PERNR switch is active and the user is linked to a personnel number in infotype 0105, subtype 0001 | An HR administrator's own record in a file can be refused even when the rest of the file posts |
| Structural authorizations | Which objects in the organizational structure the user may access, where your system uses them | Employees outside the runner's part of the structure fail with an authorization message |
Which of these objects SAP checks is set by the authorization main switches in table T77S0 (group AUTSW): P_ORGIN is the usual one, and some systems check P_ORGXX, P_ORGINCON or a customer object instead or as well; ask your HR security team which switches are on before you test. An authorization failure on some rows is the control working. Split the file by the people responsible for each population, or have it run by someone whose authorization covers all of it; never by a technical user with wider access. Simulate shows these rows before anything is written, and in the PostNow.ai portal a template can be published so that operators run it but cannot change its mapping.
Treat the spreadsheet like the system it came from
- The file is a personal data extract. Names, addresses, pay and bank details sit in it from the moment it is created. Agree with your data protection officer where it is stored, who may open it and when it is deleted, and keep only the columns the infotype needs.
- Test with prepared data. Copying production HR data into a test client is itself a data transfer; anonymised or prepared test employees are the usual answer for proving a template.
- Know what leaves the computer. PostNow.ai's agent log on the PC records parameter names and row counts for each call, not cell values. Each Run sends its results to the Posting Audit in the PostNow.ai portal: template, SAP system, client and user, the result per record and SAP's message, which can name the personnel number. With an approval policy, the rows to be posted and a copy of the workbook go to the portal for the approver. Mapping AI sends the unmatched column headers and the field names and descriptions (in screenshot mode, the screenshots the designer chooses); AI Review sends SAP's messages for the failed row, field definitions and, for BAPI templates, the length and format of each value, and the row's values only when a designer ticks the opt-in for that one analysis. Tell your data protection officer all of this before the first HR file.
- Keep the Run Log with the file. Each row shows who wrote it, when and in which system, which is the evidence an auditor asks for after a pay or bank detail change.
Retroactive changes and payroll
PostNow.ai writes the dates the file holds, and SAP payroll reacts to them: a change to a payroll-relevant infotype in a period payroll has already run sets the earliest master data change date in infotype 0003 (Payroll Status), and the next payroll run recalculates back to that date.
- A backdated file reaches every employee in it. A pay review loaded on 0008 three months back creates retroactive accounting for every employee in the file, which payroll then processes and reports as differences.
- The retroactive accounting limit stops changes that go too far back. SAP refuses changes to payroll-relevant infotypes before the earliest retroactive accounting date set in the payroll control record or in infotype 0003, whichever is later; those rows fail with SAP's message.
- Payroll needs the date before the run. Tell the payroll team which infotypes, how many employees and which start dates a file holds, and keep the run out of the window in which the payroll control record (PA03) is set to Released for payroll: in that status SAP locks changes that affect the current or past periods of that payroll area.
Worked example: 48 address changes after an office move
PostNow.ai handles this with one published PA30 template for infotype 0006, subtype 1 (permanent residence), built on a recording of PA30 Create. Forty-eight employees in personnel area 1010 have new home addresses from 01.01.2027, collected by HR in a spreadsheet. A new record from that date delimits each current address on 31.12.2026, which is what the business wants.
| Column | Row 2 |
|---|---|
| Personnel number | 00004412 |
| Subtype | 1 |
| Valid from / to | 01.01.2027 / 31.12.9999 |
| Street, postal code, city, country | 114 Foundry Road, 44114, Cleveland, US |
- Validate. Two cells are flagged: a postal code with a trailing space, and a date typed as 1/1/27. Both are fixed in the sheet.
- Simulate. 46 rows pass. One employee is locked because an HR administrator has the record open in PA30; the administrator closes it. One employee joins on 15.01.2027, so an address from 01.01.2027 starts before the entry date; HR moves that row's start date to 15.01.2027. A second Simulate is clean.
- Run. All 48 records are created. Each row's Run Log shows SAP's save message with user, time and system.
- Check. An HR administrator opens three employees in
PA20, infotype 0006: the old address ends on 31.12.2026, the new one starts on 01.01.2027, and no other subtype changed.
Every address can be traced from its Excel row to the record in SAP, and the extract taken before the run holds the old values in case one row turns out to be wrong.
SAP HR data migration: history and the initial load
PostNow.ai runs the same templates for an initial load as for daily changes, but an SAP HR data migration adds decisions that a routine upload does not raise:
- How much history to carry is an HR and legal decision. Current records only make a small file; a full history reproduces every validity period and multiplies the rows.
- Load each employee in date order. Because each record on constraints 1 and 2 delimits the one before it, history goes in from the oldest record to the newest, starting with the hire action.
- Load in dependency order. Organizational Management objects first, then the hire action with 0000, 0001 and 0002, then the other infotypes, each on its own sheet.
- Agree how payroll treats the history. Payroll status and the retroactive accounting limits decide whether loaded history is recalculated; the payroll team sets them before the load.
- Reconcile per employee. A count of records proves little; open a sample of employees and read every infotype from the hire date to today.
On SAP S/4HANA, on-premise HR keeps the PA30, PA40 and infotype model in SAP HCM for SAP S/4HANA, so the same templates apply; confirm with your Basis team which HCM version your system runs. The wider migration plan, including the objects that come before HR, is in SAP data migration and SAP master data migration.
HR upload errors and the fix
PostNow.ai writes SAP's message to each failed row, so the fix starts from the message text. These are the ones an infotype upload meets most, plus the one problem that raises no error at all:
| Message | What it means | Fix |
|---|---|---|
PG 184 Employee/applicant is not locked yet | An employee BAPI was called without BAPI_EMPLOYEE_ENQUEUE in the same session | Call the BAPI through a remote-enabled wrapper that locks, writes and releases the lock in one call |
| RFC error: the function module is not remote-enabled (CALL_FUNCTION_NOT_REMOTE) | The template calls HR_INFOTYPE_OPERATION (or another normal function module) directly | Map the template to your SAP team's remote-enabled wrapper, or record PA30 |
| Personnel number locked by another user | Someone has the employee open in PA30 or PA40, or another process holds the lock | Close the record or wait, then Retry Failed; check SM12 if the lock stays |
PG 432 Position … not available for the start date of the infotype record | The 0001 row points to a position that does not exist on that date | Create or extend the position in Organizational Management first, or correct the start date |
| No authorization for the infotype or the employee | P_ORGIN, P_PERNR or a structural authorization refuses this row for the runner | Have the row run by the administrator responsible for that population; SU53 or an authorization trace in ST01 shows which check failed |
| Record starts before the entry date | The validity begin is earlier than the employee's hire | Move the start date to the entry date or later |
| Change before the retroactive accounting limit | The date lies before the earliest retroactive accounting date for the payroll area or the employee | Agree a later date with payroll, or have payroll review the limit |
| Payroll area locked for master data changes | The payroll control record is Released for payroll while payroll runs, so changes to the current or past periods are blocked | Wait until payroll sets the control record to Exit payroll, then Retry Failed |
| No error: a record ended that should have continued | An INS row with the wrong begin date delimited the current record (time constraint 1 or 2) | Restore the old record from the extract taken before the run, then correct the date in the file |
| Run Log: UNKNOWN (PostNow.ai) | SAP's answer was lost after the row was sent, so the record may have been written | Check the employee in PA20 before posting the row again; Retry Failed leaves UNKNOWN rows alone |
Checklist before an SAP HR master data upload
PostNow.ai checks formats and allowed values and keeps operators on the published template; this list covers the decisions that stay with HR, payroll and data protection.
- One sheet per infotype and per operation, with the time constraint of each infotype and subtype read from
T582AandT591A. - The route is a PA30 or PA40 recording, or a remote-enabled wrapper that runs under the caller's user and passes
NOCOMMIT = 'X'. - Every begin date is on or after the employee's entry date and inside the period payroll has agreed.
- Life-cycle events (hire, transfer, leaving) go through a PA40 action, not a single infotype.
- Positions and organizational units referenced in 0001 exist from the record's start date.
- Change rows carry every field of the record, read from SAP, not only the changed field.
- The current records of every employee in the file are extracted and stored before the run.
- The runner's HR authorization covers every employee and infotype in the file.
- Where and for how long the file is kept is agreed with data protection, and the test client uses prepared test employees.
- Simulate has run clean on the whole file, and the first employees written have been checked in
PA20.
What to plan for in an SAP HR master data upload
PostNow.ai writes each record through PA30, PA40 or SAP's own HR function modules, so SAP's time constraints, authorizations and payroll rules decide every result.
- Run SAP's checks in Simulate. Validate checks formats and allowed values in Excel; hire dates, positions, locks and authorizations are SAP's checks and arrive when SAP sees the row.
- Read the dates as a person. A begin date one month early passes every check and delimits a record; someone in HR administration signs off the dates before Run.
- Agree the wrapper once. If you use the wrapper route, your SAP and security teams build and test it once per infotype group, and every later file reuses it.
- Load in dependency order. Organizational Management before 0001, hires before the infotypes that follow them, and in a migration each employee's history from oldest to newest.
- Keep payroll in the loop. Any file with dates in a past payroll period is announced to payroll with its scope.
- Keep re-runs in the same workbook. The re-post check reads this sheet's Run Log, and UNKNOWN rows are checked in SAP before anyone posts them again.
Making a template like this repeatable for a team (designers who build, operators who only run, a published template in the central library, approvals before the run) is covered in Excel to SAP automation. HR master data next to the other master data objects is in SAP master data mass upload, and changing existing records in bulk across objects is in SAP mass change.
Free PA30 infotype upload template
PostNow.ai publishes a free PA30 HR infotype template: one row per infotype record, with the record key (infotype, personnel number, subtype, validity begin and end) and the operation, sample rows for addresses (0006) and communication (0105), and a field guide that explains every column, including why a change row resends the whole record. Use its key columns as the start of your own template, map them to the fields of your PA30 recording or your remote-enabled wrapper, and Simulate before the first file. The other SAP master data templates are on the templates page.
