There is no API

2026-08-13

Every integration guide assumes the thing you’re integrating with has an endpoint. A REST API, a webhook, at worst a SOAP service with a WSDL from 2009. The software I work with has none of that. It has a terminal emulator, a green-on-black screen, and a keyboard buffer.

This blog is about automating that software anyway.

What that looks like in practice

A typical job: read an order out of one system, key it into another, and don’t get fired when either side changes. The “API” is whatever the screen gives you:

session = terminal.connect("prod-as400.internal", port=23)
session.wait_for("ORDER ENTRY", timeout=10)

# Field positions are the contract. Nobody documented them,
# but they haven't moved since 1997.
session.send_at(row=6, col=22, text=order.customer_id)
session.send_at(row=8, col=22, text=order.part_number)
session.send_key("ENTER")

error = session.read(row=24, col=2, length=78).strip()
if error:
    raise ScreenRejection(error)

No SDK. No versioned schema. The contract is a screen position and thirty years of nobody daring to touch it.

Rules I’ve learned the hard way

  1. The screen is the source of truth. Not the docs, not the DBA’s memory. If row 24 says it failed, it failed.
  2. Wait for state, never for time. Every sleep(2) is a production incident on a slow night.
  3. Log every screen you touch. When the automation breaks at 2am, the screen capture is the only witness.

More of this — real screens, real failures, real fixes — coming soon.