Skip to content
PYD ENTERPRISES

OpenAPI 3.1, AsyncAPI 2.6 & JSON Schema

Contracts for the new system, written by the old one.

PYD ENTERPRISES turns COMMAREAs, copybooks, EJB remotes and WCF contracts into standards-compliant OpenAPI 3.1, AsyncAPI event schemas and JSON Schema data contracts, with exact type constraints.

INTERFACE INVENTORY · LOANS186 operations
  • GET

    /loans/{loanId}/accrual

    LNINQ01 · CICS LINK

  • POST

    /loans/{loanId}/payments

    LNUPD01 · CICS BMS

  • GET

    /customers/{custNo}/loans

    LNCUS02 · VSAM AIX

  • SUB

    loans.accrual.posted

    LNACCR02 · batch WRITE

  • PUT

    /policies/{policyNo}/quote

    PolicyServiceBean · EJB

Spec viewer

Click a COBOL field. Find it in every document.

One CICS COMMAREA, three generated documents. Each property records the PIC clause, byte length and the dataflow evidence for its constraints, and the response code field becomes HTTP statuses instead of a property.

LNINQ01 · CICS TRANSID LNIQ · LINK COMMAREA 37 bytes

1 01 LNIQ-COMMAREA.
2 05 CA-LOAN-ID PIC X(10).
3 05 CA-AS-OF-DATE PIC 9(08).
4 05 CA-RESP-CODE PIC X(02).
5 88 CA-OK VALUE '00'.
6 88 CA-NOT-FOUND VALUE '04'.
7 88 CA-CLOSED VALUE '08'.
8 05 CA-PRIN-BAL PIC S9(11)V99 COMP-3.
9 05 CA-ANN-RATE PIC SV9(6) COMP-3.
10 05 CA-DAILY-ACCR PIC S9(7)V99 COMP-3.
11 05 CA-RATE-TYPE PIC X(01).
12 88 CA-RATE-FIXED VALUE 'F'.
13 88 CA-RATE-VARIABLE VALUE 'V'.

S9(11)V99 COMP-3 · 7 BYTES → principalBalance

13 digits packed into 7 bytes, 2 decimals, signed: decimal string with exactly 2 fraction digits so no client parses money as a float.

openapi/loan-accrual.yamlline 33
1openapi: 3.1.0
2info:
3 title: Loan accrual inquiry
4 version: 2026.11.04
5paths:
6 /loans/{loanId}/accrual:
7 get:
8 operationId: getDailyAccrual
9 x-pyd-source: LNINQ01.cbl:220-268
10 parameters:
11 - name: loanId
12 in: path
13 required: true
14 schema: { type: string, maxLength: 10 }
15 - name: asOf
16 in: query
17 schema: { type: string, format: date }
18 responses:
19 "200":
20 description: CA-OK ('00')
21 content:
22 application/json:
23 schema: { $ref: "#/components/schemas/Accrual" }
24 "404": { description: CA-NOT-FOUND ('04') }
25 "409": { description: CA-CLOSED ('08') }
26components:
27 schemas:
28 Accrual:
29 type: object
30 required: [loanId, principalBalance, annualRate, dailyAccrual]
31 properties:
32 loanId: { type: string, maxLength: 10 }
33 principalBalance: { type: string, pattern: "^-?[0-9]{1,11}[.][0-9]{2}$" }
34 annualRate: { type: string, pattern: "^-?0[.][0-9]{6}$" }
35 dailyAccrual: { type: string, pattern: "^-?[0-9]{1,7}[.][0-9]{2}$" }
36 rateType: { type: string, enum: [FIXED, VARIABLE] }

Data contracts

Exact types, not best guesses.

JSON Schema 2020-12 constraints come from storage definitions and from how the program actually uses each field.

Legacy definitionJSON SchemaRule
PIC X(n)string, maxLength nTrailing spaces trimmed at the boundary; LOW-VALUES treated as absent.
PIC 9(n) DISPLAYstring, pattern ^[0-9]{n}$Kept as a string when leading zeros are significant (account numbers).
PIC S9(p)V9(s) COMP-3string, decimal patternExact decimal; p integer and s fraction digits enforced.
PIC S9(4) COMP / S9(9) COMPinteger, int32 boundsRange narrowed further when every write is bounded.
88-level condition namesenumValues renamed from the 88 names; original codes kept in x-pyd-values.
OCCURS n TIMESarray, maxItems nFixed-size tables become arrays; trailing empty entries dropped.
OCCURS 0 TO n DEPENDING ONarray, minItems 0, maxItems nThe counter field disappears; array length carries it.
REDEFINES with discriminatoroneOf + discriminatorWithout a provable discriminator, flagged instead of guessed.
PIC 9(8) used as yyyymmddstring, format dateOnly when dataflow proves every source is a date.

ASYNCAPI 2.6 FOR EVENT-DRIVEN TARGETS

Batch records become events.

The nightly job writes one history record per loan into a GDG that the general ledger job reads the next morning. In a Kafka architecture that is a topic. PYD ENTERPRISES writes an AsyncAPI channel for it, with a payload schema built from the record layout and only the fields the consumers actually read.

Message names, keys and partitioning hints come from the record key (here LH-LOAN-ID). The error branch is plumbing and does not reach the contract.

LNACCR02.cbl:1210-1236 (batch output)COBOL
1 2800-WRITE-HISTORY.
2 MOVE LN-LOAN-ID TO LH-LOAN-ID
3 MOVE WS-PROC-DATE TO LH-POST-DATE
4 MOVE WS-DAILY-INT TO LH-DAILY-ACCR
5 MOVE LN-RATE-TYPE TO LH-RATE-TYPE
6 WRITE LNHIST-REC
7 IF WS-HIST-STATUS NOT = '00'
8 PERFORM 9100-LOG-IO-ERROR
9 END-IF.

FAQ

Spec synthesis questions.

From CICS to REST, step by step: the migration guide.

Where do the operations come from?

From real interface boundaries in the code: CICS programs invoked with a COMMAREA or channel, BMS screen conversations, EJB remote interfaces, SOAP port types, WCF service contracts and stored procedure signatures. PYD ENTERPRISES does not invent endpoints; each operation carries x-pyd-source pointing at the program and lines it came from.

How are HTTP methods and paths chosen?

From behavior. An operation whose call graph writes nothing becomes a GET; one that inserts becomes a POST; idempotent updates become PUT. Paths are derived from the key fields the program reads by. Naming conventions you configure are applied, and architects can rename anything before a baseline is approved.

Why are amounts strings rather than numbers?

Packed decimal values are exact. JSON numbers are commonly parsed as binary floating point, which cannot represent most cents exactly. A string with a strict decimal pattern keeps exactness across languages. You can switch to number with multipleOf if your target stack handles decimals safely.

Can PYD ENTERPRISES emit OpenAPI 3.0 instead of 3.1?

Yes. 3.1 is the default because its schemas align with JSON Schema 2020-12. A 3.0.3 compatibility output converts type arrays to nullable and lists any construct without a 3.0 equivalent in the export report.

When does it generate AsyncAPI rather than OpenAPI?

When the legacy boundary is a record stream rather than a request: batch outputs written for downstream systems, MQ messages, or GDG generations consumed by other jobs. Those become channels with message payload schemas, ready for Kafka or another broker in the target design.

Get the contracts before the build starts.

Run PYD ENTERPRISES on 100,000 lines of COBOL or Java in your private VPC and review OpenAPI specs and DMN tables tomorrow.