Skip to content
PYD ENTERPRISES

Migration guide

COBOL copybooks to JSON Schema 2020-12: every PIC clause, mapped and traced

Copybooks are the data contracts of a mainframe estate. This guide shows how to turn them into JSON Schema that APIs, event streams and data pipelines can share, without losing precision or meaning.

COBOL copybooksJSON Schema
DIFFICULTY
Moderate
OUTPUT
Rule / schema JSON
SYNTAX TRAPS
5 covered
WORKFLOW
6 steps

By Pranav Kulkarni, Head of Language Engineering · Updated 15 Oct 2026

Technical syntax challenges

Where COBOL copybooks migrations go wrong.

01

JSON has no decimal type

PIC S9(11)V99 COMP-3 holds 13 digits exactly. A JSON number parsed as a double keeps only about 15 to 17 significant digits and cannot represent most cent values exactly. For money, the schema should carry decimals as strings with a pattern, or as numbers with an explicit multipleOf and a documented decimal parsing rule.

02

COPY REPLACING generates different names

COPY ACCTREC REPLACING ==:P:== BY ==AR==. turns :P:-BALANCE into AR-BALANCE. The same copybook produces several record names across programs; the schema should be one definition with traceability to each expansion.

03

88-levels are not constraints

88 AR-ACTIVE VALUE 'A'. names a value but does not stop other values being stored. Turning 88-levels into a strict enum is right only if every program that writes the field writes one of those values, which the analyzer checks before emitting the enum.

04

OCCURS DEPENDING ON

OCCURS 0 TO 5 TIMES DEPENDING ON AR-HOLD-COUNT is an array with maxItems: 5 whose length is stored separately. In JSON the count is implicit, so the count field is derived, and fixtures check that the two always agree.

05

REDEFINES and FILLER

REDEFINES variants become oneOf alternatives, ideally selected by a discriminator field the programs test before using a variant. FILLER is dropped from the schema but kept in the layout report, because offsets downstream depend on it.

Extraction workflow

6 steps from source to signed-off spec.

The sequence a PYD ENTERPRISES Discovery Scan runs for this stack. Every output links back to source file and line range.

  1. 1

    Collect copybooks and the programs that use them

    Ingest copybook libraries and the programs that COPY them, so REPLACING expansions and real usage (which variants are read, which values are written) are visible.

  2. 2

    Compute the byte layout

    PYD ENTERPRISES computes offset, length and usage for every elementary item, including COMP-3 sizes ((digits + 1) / 2 rounded up), binary sizes and ODO maximums.

  3. 3

    Infer semantic types

    Date fields, discriminators and enums are inferred from usage: a 9(8) moved to a date routine becomes a date; a field tested before reading a REDEFINES variant becomes its discriminator.

  4. 4

    Map to JSON Schema 2020-12

    Strings get maxLength, decimals get pattern or multipleOf, arrays get min and max items, variants become oneOf and validated value sets become enums.

  5. 5

    Attach COBOL metadata

    Each property carries an x-cobol annotation with PIC, usage, offset and length so integration engineers can build converters without opening the copybook.

  6. 6

    Review and publish

    Data owners review names and inferred types, then the schemas are exported for API, event and data catalog use, with fixtures that round-trip records through the layout.

Legacy in, specification out

The source, and what PYD ENTERPRISES extracts from it.

Left: the COBOL copybooks construct as it sits in production. Right: the reviewed artifact your JSON Schema engineers build against. PYD ENTERPRISES produces the spec and the tests; your team writes the service.

LEGACY SOURCE

ACCTREC.cpyCOBOL
1 * used as: COPY ACCTREC REPLACING ==:P:== BY ==AR==.
2 01 :P:-ACCOUNT.
3 05 :P:-ACCT-NO PIC X(12).
4 05 :P:-ACCT-STATUS PIC X(01).
5 88 :P:-ACTIVE VALUE 'A'.
6 88 :P:-CLOSED VALUE 'C'.
7 88 :P:-FROZEN VALUE 'F'.
8 05 :P:-BALANCE PIC S9(11)V99 COMP-3.
9 05 :P:-OPEN-DATE PIC 9(08).
10 05 :P:-HOLD-COUNT PIC S9(4) COMP.
11 05 :P:-HOLDS OCCURS 0 TO 5 TIMES
12 DEPENDING ON :P:-HOLD-COUNT.
13 10 :P:-HOLD-AMT PIC S9(7)V99 COMP-3.
14 10 :P:-HOLD-REASON PIC X(02).

EXTRACTED ARTIFACT

AR-ACCOUNT.schema.jsonJSON
1{
2 "$schema": "https://json-schema.org/draft/2020-12/schema",
3 "title": "Account (ACCTREC, AR-ACCOUNT)",
4 "type": "object",
5 "required": ["acctNo", "acctStatus", "balance", "openDate", "holds"],
6 "properties": {
7 "acctNo": { "type": "string", "maxLength": 12, "x-cobol": "X(12) @0 len 12" },
8 "acctStatus": { "enum": ["A", "C", "F"], "x-cobol": "X(1) @12, 88-levels verified" },
9 "balance": {
10 "type": "string", "pattern": "^-?\\d{1,11}\\.\\d{2}$",
11 "x-cobol": "S9(11)V99 COMP-3 @13 len 7"
12 },
13 "openDate": { "type": "string", "format": "date", "x-cobol": "9(8) yyyymmdd @20" },
14 "holds": {
15 "type": "array", "maxItems": 5,
16 "x-cobol": "OCCURS 0 TO 5 DEPENDING ON AR-HOLD-COUNT (S9(4) COMP @28) @30",
17 "items": {
18 "type": "object",
19 "properties": {
20 "holdAmt": { "type": "string", "pattern": "^-?\\d{1,7}\\.\\d{2}$", "x-cobol": "S9(7)V99 COMP-3 len 5" },
21 "holdReason": { "type": "string", "maxLength": 2 }
22 }
23 }
24 }
25 }
26}

Architectural best practices

Build the JSON Schema side to the spec, not to the old shape.

  • Carry money as decimal strings or with a documented decimal parsing rule; never let a double parser touch it.
  • Keep one schema per copybook and record each REPLACING expansion as an alias, not a copy.
  • Emit enums only for value sets confirmed by every writer; otherwise document the 88-level names as known values.
  • Keep layout metadata (offset, length, usage) on every property so converters can be built and tested from the schema alone.
  • Version schemas with the copybook: a changed PIC clause is a breaking change for every consumer.

One copybook, many consumers

In most estates a handful of copybooks describe the records that matter: account, customer, policy, claim, transaction. They are included in hundreds of programs, written to VSAM and sequential files, sent over MQ and passed in COMMAREAs. When those records move to APIs, Kafka topics and data platforms, every team needs the same contract. Hand-written schemas drift within weeks.

PYD ENTERPRISES generates JSON Schema 2020-12 from the copybook and the programs that use it, with byte-level metadata and source links. The schema becomes the shared contract; consumers generate their own types from it. PYD ENTERPRISES does not build the converters or the APIs, but the schema plus fixtures make both straightforward to build and test.

Checking the byte arithmetic

The example record is variable length. The fixed part is 12 + 1 + 7 + 8 + 2 = 30 bytes: account number, status, a 13-digit packed balance (7 bytes), an 8-byte date and a binary halfword count. Each hold adds a 9-digit packed amount (5 bytes) and a 2-byte reason, so 7 bytes per occurrence, giving 30 to 65 bytes in total. The layout report shows those offsets, and the generated fixtures include records with zero and five holds to exercise both ends of the range.

FAQ

COBOL copybooks to JSON Schema questions

Can PYD ENTERPRISES emit OpenAPI components instead of standalone schemas?

Yes. OpenAPI 3.1 uses JSON Schema 2020-12 directly, so the same schemas are exported as standalone files or as components referenced by generated operations.

How are REDEFINES without a clear discriminator handled?

If no program tests a field before choosing a variant, the schema emits oneOf without a discriminator and the copybook is flagged for review, often revealing that one variant is obsolete.

Are AsyncAPI schemas supported for MQ or Kafka records?

Yes. The same record schemas can be referenced from AsyncAPI 2.6 channel definitions for queue or topic payloads.

Get the spec for your COBOL copybooks estate.

Request a codebase scan and review extracted rules, contracts and fixtures for your own COBOL copybooks estate, inside your VPC.