Written by Daniel Ashcraft — 12+ years building industrial software including SCADA modernization, IoT data pipelines, and WebGL 3D visualization for manufacturing and energy companies.
The practical route to AS400 API integration is to leave your RPG where it is and put a REST layer in front of it. IBM's Integrated Web Services (IWS) server ships with IBM i and can publish RPG programs and SQL statements as REST endpoints. For read-heavy work, querying Db2 for i over JDBC or ODBC is often simpler still.
Most IBM i shops don't need a rewrite to get there. The data is already in Db2 for i, the business rules are already in RPG and CL, and IBM supports several ways to call both from outside the box. The options below run roughly in the order we reach for them. For the wider method, including vendor systems you didn't write, see the guide to legacy system integration with reverse engineering and AI.
What are the options for putting an API on an AS400?
There are six: IWS REST services over RPG programs, IWS REST over SQL, direct Db2 for i access through JDBC or ODBC, stored procedures that wrap programs, data queues, and 5250 screen automation. Pick by what the caller needs. Business logic that only exists in RPG means calling the program; data alone means reading the database; a change notice means an event.
| Approach | Best for | What you need on IBM i | Watch out for |
|---|---|---|---|
| IWS REST over an RPG program or service program | Calling existing business logic (pricing, credit checks, order entry) synchronously | HTTP Group PTF, Java, program compiled with PCML | Parameter lists designed for green screens, not for JSON |
| IWS REST over SQL statements | Simple CRUD on tables you control | IBM i 7.3 or later with the HTTP Group PTF | Skips any validation the RPG layer does |
| Db2 for i through JDBC (JTOpen) or ODBC | Reporting, analytics, syncing data into a warehouse or a new app | Host servers running, a user profile with the right object authority | Reading files the RPG treats as private, writing around business rules |
| Stored procedure wrapping a program | Reusing RPG from any SQL client | A CREATE PROCEDURE statement; no change to the program | Parameter type mismatches (packed versus zoned decimal) |
| Data queues | Event-style integration: order released, shipment confirmed, label printed | A *DTAQ object and one added call in the RPG that already knows about the event | No commitment control, retry or dead-letter handling |
| 5250 screen automation | Vendor packages where you cannot touch the code or the files | A tool such as IBM HATS, a stable screen flow | Breaks when a screen changes; slow; ties up interactive jobs |
Most of our IBM i projects use two or three of these: JDBC reads for dashboards, an IWS service or two for order entry, and a data queue that reports changes on the floor.
How does IWS turn an RPG program into a REST endpoint?
IWS reads the Program Call Markup Language (PCML) that the RPG compiler embeds in your program and generates a web service that maps JSON fields to its parameters. You choose the URL template, the HTTP method, and where each parameter comes from.
IBM describes the Integrated Web Services server as part of the operating system, with SOAP and REST support and no up-front cost. It needs the current HTTP Group PTF and Java. To make a program deployable, compile it with PCML embedded. IBM's RPG Cafe note on PCML generation gives the keyword: PGMINFO(*PCML : *MODULE), with *DCLCASE added if you want the generated names to keep the mixed case from your source.
Here is the entry interface of a small order status program in free-form RPG. The business logic is untouched; only the control option is new:
**free
ctl-opt dftactgrp(*no) pgminfo(*pcml : *module : *dclcase);
dcl-pi *n;
orderNo char(10);
orderStatus char(2);
shipYmd packed(8 : 0);
end-pi;
// existing lookup logic, unchanged
*inlr = *on;
return;
Deploy it through the Web Administration for i wizard, pick REST, and define a resource such as /orders/{orderNo}. IBM's REST tutorial for IWS shows the details: a {id} variable in the URI template is injected into a program parameter by setting its input source to *PATH_PARAM, each HTTP method can map to a different procedure in a service program, and an optional parameter can carry the HTTP status code the program wants to return. The default context root is /web/services, so the URL ends in /web/services/orders/A123456789.
If you are starting now, build on IWS 3.0. It is built on Jakarta EE instead of Java EE, requires Java 17, and turns on an OpenAPI UI by default at /openapi/ui/ with a combined YAML spec at /openapi/. It needs HTTP Group SF99962 level 6 plus PTF SJ07853 on 7.6, SF99952 level 25 plus SJ07854 on 7.5, or SF99662 level 47 plus SJ07855 on 7.4, and IBM says future releases will not allow creating new IWS 2.6 servers. If you are still on 7.4, note that IBM withdrew it from marketing on April 30, 2026 and its standard support ended September 30, 2026, per IT Jungle's coverage of announcement letter AD25-0894. Plan the API work and the OS upgrade together.
The weak point of IWS over RPG is the parameter list. Programs written for 5250 screens often take a 500-byte data structure, return errors in an indicator array, or expect the library list of an interactive user. Those need a thin wrapper program with a clean interface before you publish them. Writing that wrapper is where most of the integration effort goes.
How do you secure an IWS REST service?
Turn on authentication, require TLS, and restrict which roles can call each service. IWS will publish a service without any of those if you let it.
IBM's page on IWS user registries, groups and roles covers the controls. By default the registry is based on IBM i user profiles, and *BASIC authentication means the client sends a user ID and password. You can assign roles to a whole service or a subset of roles to each procedure; if you assign none, every authenticated user can call it. The "secure transport is required" option needs an SSL endpoint configured on the server, and IBM recommends it whenever passwords cross the wire. Give the profile the service runs under only the object authority it needs. If outside partners or a public app will call the API, put a gateway in front of IWS for OAuth tokens, API keys and rate limits.
When should you go straight to Db2 for i with JDBC or ODBC?
Go straight to the database when the caller needs data and the rules for reading it are simple. Reporting, warehouse loads, search indexes and read-only portals rarely need RPG in the path.
For Java and anything on the JVM, use JTOpen, the open source edition of the IBM Toolbox for Java. It is published to Maven Central as net.sf.jt400:jt400, includes a JDBC driver, and is actively maintained; version 21.0.7 was published on GitHub on July 31, 2026. Its JDBC properties control the things IBM i developers care about: naming (sql or system), libraries (the library list for the server job), secure for TLS, and errors=full for usable error text.
For .NET, Python, Node.js on Linux or Windows, and BI tools, IBM ships an ODBC driver in the IBM i Access Client Solutions Windows and Linux application packages. IBM also introduced Mapepire in 2024, an open source Db2 for i server and client set that talks over secure WebSockets on a single port, with clients for Python, Node.js and Java.
Two operational details catch teams. Each JDBC or ODBC connection is served by a database server job (QZDASOINIT) on IBM i, so a new web app that opens connections freely can flood the system; use a connection pool on the client side. And character data is stored in EBCDIC with a CCSID per column, so a file created with CCSID 65535 will come back as raw bytes unless you fix the column or tell the driver how to translate it.
The bigger risk with direct access is writes. If an order header in ORDHDR is only ever updated by an RPG program that also writes an audit record, adjusts allocation in another file and sends a data queue message, an SQL UPDATE from outside skips all of that. Read directly; write through the program, a stored procedure or an IWS service.
How do you wrap an existing RPG program in a stored procedure?
Register the program with an external CREATE PROCEDURE statement. Db2 for i then calls the compiled program directly, with no change to its source, and any SQL client can run it with CALL.
The external procedure syntax takes LANGUAGE RPGLE, an EXTERNAL NAME pointing at the program, and a parameter style. PARAMETER STYLE GENERAL passes only the parameters in the CALL, which matches how an RPG program already expects to be called. IBM's own support example uses the same form. For the program above:
CREATE OR REPLACE PROCEDURE APILIB.GET_ORDER_STATUS (
IN ORDER_NO CHAR(10),
OUT ORDER_STATUS CHAR(2),
OUT SHIP_YMD DECIMAL(8, 0)
)
LANGUAGE RPGLE
SPECIFIC APILIB.GETORDSTS
NOT DETERMINISTIC
NO SQL
CALLED ON NULL INPUT
EXTERNAL NAME 'ORDLIB/ORDSTSR'
PARAMETER STYLE GENERAL;
Three details trip people up. DECIMAL in SQL is packed, which matches packed(8 : 0) in RPG; if the program declares a zoned field, use NUMERIC instead. The data access clause must match the program's embedded SQL: NO SQL if it has none, READS SQL DATA if it only selects, and the default MODIFIES SQL DATA if it inserts, updates or deletes. And the procedure runs in the database server job, not an interactive session, so any library list the program assumes has to come from the connection (the JDBC libraries property) or from qualified names.
Calling it from Java with JTOpen:
import java.math.BigDecimal;
import java.sql.CallableStatement;
import java.sql.Connection;
import java.sql.DriverManager;
import java.sql.Types;
public class OrderStatusClient {
public static void main(String[] args) throws Exception {
String url = "jdbc:as400://ibmi.example.com;naming=sql;libraries=APILIB,ORDLIB;secure=true;errors=full";
try (Connection conn = DriverManager.getConnection(url, System.getenv("IBMI_USER"), System.getenv("IBMI_PASSWORD"));
CallableStatement cs = conn.prepareCall("CALL APILIB.GET_ORDER_STATUS(?, ?, ?)")) {
cs.setString(1, "A123456789");
cs.registerOutParameter(2, Types.CHAR);
cs.registerOutParameter(3, Types.DECIMAL);
cs.execute();
String status = cs.getString(2);
BigDecimal shipYmd = cs.getBigDecimal(3);
System.out.println(status + " " + shipYmd);
}
}
}
For plain table access over HTTP, IWS can also publish REST APIs based on SQL statements on IBM i 7.4 (HTTP Group SF99662) and 7.3 (SF99722 level 19). Each HTTP method maps to an SQL statement, path parameters bind to parameter markers, output is JSON, and a failed statement returns HTTP 500 with the SQLSTATE. Use it for lookup tables, not for data with business rules behind it.
Modernizing Manufacturing Systems?
Get a free architecture review for your industrial software. IoT integration and legacy migration expertise.
Download: Manufacturing Legacy Modernization Checklist
Zero-downtime migration playbook for SCADA, MES & ERP systems. Includes system assessment, risk matrix, ROI calculator, and phased cutover plan.
Where do data queues fit in an IBM i integration?
Data queues let RPG send an event out without waiting on a network call. The program that already knows something happened writes a message to a *DTAQ, and a listener job in Java, Node.js or SQL forwards it to a REST endpoint, a message broker or a webhook.
They are our default for getting changes off the box. RPG has called the QSNDDTAQ API for decades, so adding one call where an order is released is a small change. Since the 7.4 TR1 and 7.3 TR7 Technology Refreshes you can also work with data queues from SQL: QSYS2.SEND_DATA_QUEUE sends character, UTF-8 or binary messages, and the QSYS2.RECEIVE_DATA_QUEUE table function reads them, with a WAIT_TIME parameter (negative waits forever). The sender columns are only filled in if the queue was created with SENDERID(*YES); the default is *NO.
SELECT MESSAGE_DATA_UTF8, SENDER_JOB_NAME, SENDER_CURRENT_USER
FROM TABLE(QSYS2.RECEIVE_DATA_QUEUE(
DATA_QUEUE => 'ORDEVT',
DATA_QUEUE_LIBRARY => 'APILIB',
WAIT_TIME => 30));
From Java, JTOpen's DataQueue class does the same thing over the host servers. read(int wait) blocks for up to that many seconds and returns null when nothing arrived. Using SecureAS400 instead of AS400 encrypts the connection, provided the host servers are configured for TLS:
import com.ibm.as400.access.AS400;
import com.ibm.as400.access.DataQueue;
import com.ibm.as400.access.DataQueueEntry;
import com.ibm.as400.access.SecureAS400;
public class OrderEventListener {
public static void main(String[] args) throws Exception {
char[] password = System.getenv("IBMI_PASSWORD").toCharArray();
try (AS400 system = new SecureAS400("ibmi.example.com", System.getenv("IBMI_USER"), password)) {
DataQueue queue = new DataQueue(system, "/QSYS.LIB/APILIB.LIB/ORDEVT.DTAQ");
while (true) {
DataQueueEntry entry = queue.read(30);
if (entry != null) {
System.out.println(entry.getString());
}
}
}
}
}
A production listener also needs reconnect logic, backoff and a clean shutdown, which the sample leaves out. More important, reading removes the entry by default, and IBM's journaling docs state that commitment control does not support data queues, so a queue message cannot roll back with the database change that caused it. For anything financial, have the RPG write the event to a table in the same commitment control transaction as the business change, use the queue only as a wake-up signal, and have the listener sweep for unsent rows on a timer in case a signal is lost. The listener can crash between the POST and marking the row sent, so give each event an ID the receiver uses to drop duplicates.
Is 5250 screen scraping ever the right answer?
Only when you cannot change the code or safely touch the files, which usually means a licensed vendor package. Screen automation replays a user's keystrokes, so it inherits the application's validation, but it is slow and breaks when a screen changes.
IBM HATS is the established tool here. It can turn 5250, 3270 and VT terminal flows recorded with its macro editor into JAX-RS REST or JAX-WS SOAP services. With a vendor ERP on IBM i, check the license before you call its programs or read its files directly; some agreements restrict that, and the post on whether it is legal to reverse engineer software covers the questions to ask. This is not legal advice; review your license agreement and MSA with counsel.
Can RPG call outside REST APIs too?
Yes. Integration usually runs both ways, and Db2 for i has SQL functions for outbound HTTP calls that RPG can run through embedded SQL. IBM's page on the QSYS2 HTTP functions says they run without the overhead of creating a JVM, use the IWS client transport, and have lower overhead than the older SYSTOOLS HTTP functions. They support authentication, proxies and configurable SSL options.
What do commercial AS400 modernization tools add?
Commercial tools mostly add packaging: an API designer, generated OpenAPI documents, authentication, logging and a support contract. They use the entry points described above, so you still need to understand your programs.
Profound API from Profound Logic, for example, is a low-code product that builds REST APIs over Db2, RPG programs and ILE procedures, runs on Node.js and Express, and generates OpenAPI documentation, according to the vendor. IWS 3.0 now covers OpenAPI at no extra cost, and IBM's open source Node.js itoolkit can call RPG programs through XMLSERVICE without changing them. A commercial tool earns its cost when you will publish many services, want one place to manage keys and logging, and have no Java or Node.js developers in house.
Why is the IBM i skills shortage pushing shops toward APIs?
IBM i skills are getting harder to find, and an API lets everyone else work against IBM i without learning it. In Fortra's 2026 IBM i Marketplace Survey, IBM i skills became the top concern for the first time, ending cybersecurity's nine-year run.
According to IT Jungle's write-up, 69% of 315 respondents named IBM i skills as a top concern (Fortra's own report says 320 users completed the survey), up from 60% in 2025 and 45% in 2020. The full Fortra report shows how much code is at stake: 73% of respondents run homegrown applications on IBM i, and RPG (88%) and SQL (82%) remain the main languages for new development.
With an API in place, a web developer who knows REST can build the customer portal or the MES integration without opening a source member, while one RPG developer keeps the core stable. The boundary also lets you replace functions one at a time later, as with Epicor Kinetic integrations.
How can AI help you read RPG and build the wrappers?
AI models can speed up the slow part of IBM i integration: summarizing fixed-format RPG, proposing what each parameter and indicator means, and drafting the wrapper program, the CREATE PROCEDURE statement and the tests. They still guess wrong about indicators and file relationships often enough that every draft needs checking against the running system.
The IBM Bob Premium Package for i, announced as generally available in July 2026, explains RPG and COBOL programs, converts fixed-format RPG to free-format, and generates unit tests and documentation. API generation is not on that list.
The method that holds up is the one from the legacy API reverse engineering case study, an undocumented SOAP CRM API with 12+ services that two earlier teams had given up on: enumerate, probe, validate, abstract. For IBM i that means:
- Enumerate the programs that matter. Use AI to summarize each one's parameters, files read and written, and data queues touched, from the source and a
DSPPGMREFlisting. - Probe each candidate in a test partition or a copy of the libraries. Call it with known inputs through the stored procedure and record every output.
- Validate by turning those recordings into characterization tests that run in CI against the wrapper, so a later RPG change that alters behavior fails a build.
- Abstract behind a clean JSON contract, publish through IWS or your gateway, and version it.
On that CRM project, schema validation caught three vendor-side changes before they reached production. Characterization tests give you that warning when someone edits the RPG behind a published service.
What should you inventory before you start?
Start with a list of the ten business events and lookups other systems ask your IBM i for, and for each one write down the program or file that owns it. That owner points to the approach for most items, and the exceptions are where you'll spend your design time.
Then check five things: your IBM i release and HTTP Group PTF level, whether the key physical files are journaled, which programs have clean parameter lists versus screen-oriented ones, who will authenticate to the API and with what profile, and who on staff can still read the RPG. This kind of inventory is where our legacy system modernization and manufacturing software development work usually starts, if you want a second set of eyes on it.
Download: Manufacturing Legacy Modernization Checklist
Zero-downtime migration playbook for SCADA, MES & ERP systems. Includes system assessment, risk matrix, ROI calculator, and phased cutover plan.