Integra Output Format Schemas
Complete guide for integrating with Integra AL3 parser outputs.
Quick Reference
| Format | Schema File | When to Use |
|---|---|---|
| JSON | json-output.schema.json |
REST APIs, web applications, single-file processing |
| NDJSON | json-output.schema.json |
Streaming, batch processing, line-by-line ingestion |
| CSV | csv-output.schema.json |
Excel, SQL databases, flat file systems |
Optional Reference:
- al3-groups-dictionary.schema.json - Complete AL3 group catalog with all 278 groups and their data elements
Output Formats Explained
JSON Format (Array with Metadata)
Structure:
{
"policies": [
{
"code": "2TRG",
"level": 2,
"iteration": 1,
"dataElements": {
"Transaction Type": "01"
},
"children": [...]
}
],
"metadata": {
"parseTime": "2026-01-31T17:20:00Z",
"groupCount": 2
}
}
Note: Validation results are provided via HTTP headers (
X-Integra-Validation-Status, etc.) and the/v1/validateendpoint. They are not included in the parsed JSON body.
Use Cases: - REST API responses - Single-file processing - When you need metadata (parse time, counts)
Schema: json-output.schema.json
NDJSON Format (Newline-Delimited JSON)
Structure:
{"code":"2TRG","level":2,"dataElements":{...},"children":[...]}
{"code":"5BPI","level":5,"dataElements":{...}}
Each line is a complete JSON object (same as items in the JSON policies array).
Use Cases: - Streaming data pipelines - Batch processing (process line-by-line) - BigQuery, Snowflake, Kafka - Large files (memory-efficient)
Schema: Same json-output.schema.json - each line is one Group object
CSV Format (Flattened)
Structure:
The CSV output follows RFC 4180 standards.
- Forced Quotes: All fields are enclosed in double quotes "".
- Escaping: Double quotes within data are escaped as "".
- Flattened: Hierarchical data is flattened into rows, with ParentID and NodeID columns to reconstruct relationships.
"ID","RefID","Key","Name","FormattedValue","ActualValue","RawValue","GroupCode","Level","NodeID","ParentID"
"1","1","5BPI","Premium Amount","$1234.56","1234.56","0000123456F","5BPI","5","12","4"
"2","1","5BPI","Effective Date","2024-01-15","2024-01-15","20240115","5BPI","5","12","4"
Columns Explained:
| Column | Description |
|---|---|
ID |
Unique ID for the data element row |
RefID |
Reference ID (internal use) |
Key |
Data Element Name (e.g. "Premium Amount") |
Name |
Same as Key (for backwards compatibility) |
FormattedValue |
Value formatted for display (e.g. "$1234.56") |
ActualValue |
Unformatted string representation of the typed value (e.g. "1234.56") |
RawValue |
Original fixed-width raw value from AL3 file |
GroupCode |
AL3 Group Code (e.g. "5BPI") |
Level |
Group Level (e.g. "5") |
NodeID |
Unique ID of the Group this element belongs to |
ParentID |
ID of the parent Group (allows reconstructing the tree) |
Understanding Hierarchy in CSV:
Since CSV is flat, we use NodeID and ParentID to represent the AL3 tree structure.
- Every Group is assigned a unique NodeID.
- Every Group (except roots) refers to its parent via ParentID.
- You can join rows on NodeID = ParentID to find children.
Field Logic Patterns (JSON/NDJSON)
In JSON output (and NDJSON), the primary key contains the Actual Value. Additional keys with suffixes are provided when representations differ.
1. Actual Value (Primary Key)
The standard field name contains the processed, typed value (as number, string, boolean, or date string).
{
"Premium Amount": 1234.56, // Numeric
"Effective Date": "2025-01-17", // String (ISO Date)
"Active": true // Boolean
}
2. Formatted Value (- Formatted)
Present only if the human-readable description differs from the Actual Value. Common for Coded fields where Actual is the code (e.g. "01") and Formatted is the description (e.g. "Basic Coverage").
{
"Coverage Type": "01",
"Coverage Type - Formatted": "Basic Coverage"
}
3. Raw Value (- Raw)
Present only if the original raw bytes differ from the Actual/Formatted representations. Useful for debugging or exact reproduction.
{
"Premium Amount": 1234.56,
"Premium Amount - Raw": "0000123456F"
}
If the raw value is effectively same as actual (e.g. text fields), this key is omitted to save space.
Personal Name Expansion
Names with format code P (Personal) are expanded into separate components:
Input (AL3):
PSMITH JANE ANN JR MS
Output (JSON):
{
"Insured Name - Prefix": "MS",
"Insured Name - FirstName": "JANE",
"Insured Name - MiddleName": "ANN",
"Insured Name - LastName": "SMITH",
"Insured Name - Suffix": "JR",
"Insured Name - Raw": "PSMITH JANE ANN JR MS "
}
Format Codes:
- P (Personal): Expanded into components (shown above)
- C (Commercial): Single consolidated string
- F (Family): Single consolidated string
- G (Generic): Single consolidated string
- Blank: Single consolidated string
Non-Personal Names:
{
"Agent Name": "ABC INSURANCE AGENCY INC",
"Agent Name - Raw": "CABC INSURANCE AGENCY INC"
}
Integration Examples
Python
JSON Format
import json
# Load JSON file
with open('output.json') as f:
data = json.load(f)
# Iterate through policies
for policy in data['policies']:
print(f"Group: {policy['code']} (Level {policy['level']})")
# Access data elements
elements = policy.get('dataElements', {})
if 'Premium Amount' in elements:
print(f" Premium: {elements['Premium Amount']}")
print(f" Premium (Raw): {elements.get('Premium Amount - Raw')}")
# Process children recursively
for child in policy.get('children', []):
print(f" Child: {child['code']}")
NDJSON Format (Memory-Efficient)
import json
# Process line-by-line (no memory issues with large files)
with open('output.ndjson') as f:
for line in f:
policy = json.loads(line)
# Same structure as JSON array items
print(f"Group: {policy['code']}")
print(f"Data: {policy['dataElements']}")
# Can process millions of records efficiently
JavaScript/Node.js
JSON Format
const fs = require('fs');
// Load JSON file
const data = JSON.parse(fs.readFileSync('output.json', 'utf8'));
// Iterate through policies
data.policies.forEach(policy => {
console.log(`Group: ${policy.code} (Level ${policy.level})`);
// Access data elements
const elements = policy.dataElements || {};
if (elements['Premium Amount']) {
console.log(` Premium: ${elements['Premium Amount']}`);
}
// Process children
(policy.children || []).forEach(child => {
console.log(` Child: ${child.code}`);
});
});
NDJSON Format (Stream Processing)
const fs = require('fs');
const readline = require('readline');
// Stream-based processing (memory-efficient)
const rl = readline.createInterface({
input: fs.createReadStream('output.ndjson'),
crlfDelay: Infinity
});
rl.on('line', (line) => {
const policy = JSON.parse(line);
console.log(`Group: ${policy.code}`);
console.log(`Data: ${JSON.stringify(policy.dataElements)}`);
});
rl.on('close', () => {
console.log('Processing complete');
});
SQL (PostgreSQL with JSONB)
Import JSON Data
-- Create table
CREATE TABLE al3_policies (
id SERIAL PRIMARY KEY,
data JSONB NOT NULL
);
-- Import JSON (flattened from policies array)
-- Use a script to split the array into individual rows
COPY al3_policies (data) FROM '/path/to/policies.ndjson';
Query Examples
-- Get all premium amounts
SELECT
data->>'code' as group_code,
data->'dataElements'->>'Premium Amount' as premium,
data->'dataElements'->>'Effective Date' as effective_date
FROM al3_policies
WHERE data->>'level' = '5';
-- Search for specific names
SELECT
data->>'code',
data->'dataElements'->>'Insured Name - LastName' as last_name,
data->'dataElements'->>'Insured Name - FirstName' as first_name
FROM al3_policies
WHERE data->'dataElements'->>'Insured Name - LastName' = 'SMITH';
-- Aggregate by group code
SELECT
data->>'code' as group_type,
COUNT(*) as count,
AVG((data->'dataElements'->>'Premium Amount')::numeric) as avg_premium
FROM al3_policies
GROUP BY data->>'code';
Apache Spark (PySpark)
from pyspark.sql import SparkSession
# Initialize Spark
spark = SparkSession.builder.appName("AL3Parser").getOrCreate()
# Read NDJSON (most efficient for Spark)
df = spark.read.json("output.ndjson")
# Show schema
df.printSchema()
# Query data
df.select(
"code",
"level",
"dataElements.Premium Amount"
).show()
# Filter and transform
premiums = df.filter(df.code == "5BPI") \
.select("dataElements.Premium Amount") \
.collect()
Pandas (Python)
import pandas as pd
import json
# Load NDJSON into DataFrame
with open('output.ndjson') as f:
data = [json.loads(line) for line in f]
df = pd.DataFrame(data)
# Expand dataElements into columns
elements_df = pd.json_normalize(df['dataElements'])
result = pd.concat([df[['code', 'level', 'iteration']], elements_df], axis=1)
# Analyze
print(result['Premium Amount'].describe())
print(result.groupby('code').size())
Schema Validation
Using ajv-cli (Node.js)
# Install
npm install -g ajv-cli ajv-formats
# Validate JSON output
ajv validate \
-s json-output.schema.json \
-d output.json \
--spec=draft2020
# Validate NDJSON (validate each line)
cat output.ndjson | while read line; do
echo "$line" | ajv validate -s json-output.schema.json -d - --spec=draft2020
done
Using Python jsonschema
import json
import jsonschema
# Load schema
with open('json-output.schema.json') as f:
schema = json.load(f)
# Validate JSON
with open('output.json') as f:
data = json.load(f)
jsonschema.validate(data, schema)
# Validate NDJSON
with open('output.ndjson') as f:
for line in f:
policy = json.loads(line)
# Validate against Group definition
jsonschema.validate(policy, schema['$defs']['Group'])
Complete Examples
Example 1: Policy with Coverage
Input AL3: Policy with basic information and coverage details
Output JSON:
{
"policies": [
{
"code": "2TRG",
"level": 2,
"iteration": 1,
"dataElements": {
"Transaction Type": "01"
},
"children": [
{
"code": "5BPI",
"level": 5,
"iteration": 1,
"dataElements": {
"Policy Number": "POL123456",
"Effective Date": "2025-01-17",
"Effective Date - Raw": "20250117",
"Premium Amount": "1234.56",
"Premium Amount - Raw": "0000123456F",
"Insured Name - Prefix": "MS",
"Insured Name - FirstName": "JANE",
"Insured Name - LastName": "SMITH",
"Insured Name - Raw": "PSMITH JANE ..."
},
"children": [
{
"code": "7COV",
"level": 7,
"iteration": 1,
"dataElements": {
"Coverage Type": "01",
"Coverage Type - Formatted": "Baseboard | Basic",
"Coverage Limit": "500000.00",
"Coverage Limit - Raw": "0050000000{"
},
"children": []
}
]
}
]
}
],
"metadata": {
"parseTime": "2026-01-31T20:30:00Z",
"groupCount": 3
}
}
Same as NDJSON:
{"code":"2TRG","level":2,"iteration":1,"dataElements":{"Transaction Type":"01"},"children":[...]}
{"code":"5BPI","level":5,"iteration":1,"dataElements":{...},"children":[...]}
{"code":"7COV","level":7,"iteration":1,"dataElements":{...},"children":[]}
FAQ
Q: Do I need both json-output.schema.json and al3-groups-dictionary.schema.json?
A: No. You only need json-output.schema.json for integration. The dictionary is an optional reference to see all possible AL3 groups and their fields.
Q: How do I handle NDJSON vs JSON?
A: Use the same schema (json-output.schema.json). For NDJSON, validate each line against the Group definition at $defs/Group.
Q: Why are some fields missing "-Raw" suffix?
A: Only fields with different formatted vs raw values include the "-Raw" suffix. If the value is already in final form (like text fields), no "-Raw" suffix is added.
Q: How do I know which groups will appear in my output?
A: It depends on your AL3 input file. Use the al3-groups-dictionary.schema.json to see all possible groups and their fields.
Q: What if a personal name doesn't have all components?
A: Missing components are omitted. For example, if there's no middle name, the "MiddleName" field won't appear.
Q: How do I handle hierarchical data?
A: Use the children array. Each Group can contain child Groups, forming a tree structure that mirrors the AL3 hierarchy.
Integra Schema Definitions
This directory contains the public JSON schemas for Integra output formats.
API Documentation (Swagger/OpenAPI)
Integra provides an interactive API documentation and testing interface.
- Swagger UI: Visit
/swagger/index.html(e.g.,http://localhost:8080/swagger/index.html) to explore endpoints and test requests interactively. - OpenAPI Spec: The raw OpenAPI 3.0 specification is available at
/openapi.yaml.
You can import openapi.yaml into tools like Postman or Insomnia to automatically configure the API collection.
API Validation Headers
All API responses (JSON, CSV, Parquet, NDJSON) include the following headers to provide immediate validation feedback:
X-Integra-Validation-Status:trueif valid,falseif errors exist.X-Integra-Error-Count: Number of validation errors.X-Integra-Warning-Count: Number of validation warnings.X-Processing-Time: Total processing duration.
If X-Integra-Validation-Status is false, you can request the full validation report by sending the same file to the /v1/validate endpoint.
Support
For questions or issues with schema integration: - Review the schema files in this directory - Check the examples above - Validate your output against the schemas - Contact support with specific validation errors
AL3 Data Types Reference
Understanding AL3 data types is crucial for interpreting values and generating valid input.
Numeric Types
| Type | Description | Example Input | Parsed Value |
|---|---|---|---|
| N0 | Numeric (integer) | 00123 |
123 |
| N2 | Numeric (2 implied decimals) | 12345 |
123.45 |
| S0 | Signed Numeric (integer) | 0012K (-122) |
-122 |
| S2 | Signed Numeric (2 decimals) | 1234K |
-123.42 |
| WD | Whole Dollars (Signed) | 00100 |
100 |
| PCT | Percentage (3 integer + 1 decimal) | 123 |
12.3 |
| MOD | Modification Factor | 12345 |
1.2345 |
Note: Signed fields in AL3 often use "overpunch" characters (last digit + sign combined). Integra automatically decodes these into standard negative numbers.
Date & Time
| Type | Format | Example | Description |
|---|---|---|---|
| DT8 | YYYYMMDD | 20250117 |
Standard date format |
| DT6 | YYMMDD | 250117 |
Legacy 2-digit year (avoid in generation) |
| D4Y | MMYYYY | 012025 |
Month and Year only |
| TI | HHMM | 1430 |
24-hour time |
| TM6 | HHMMSS | 143000 |
Time with seconds |
Text & Coded
| Type | Description | Notes |
|---|---|---|
| AN | Alphanumeric | Uppercase A-Z, 0-9, special chars |
| CD | ACORD Code | Value is a code (e.g., "01"). See schema for descriptions. |
| IC | Industry Code | Use defined industry standard codes. |
| Y/N | Boolean | "Y" = true, "N" = false, "?"/Blank = null |
Validation Rules
When generating or validating AL3 files, Integra enforces the following strict rules:
1. Structural Integrity
- Header (1MHG): Every transaction must start with a
1MHG(Message Header) group. - Trailer (1MTG): Every transaction must end with a
1MTG(Message Trailer) group. - Hierarchy: Groups must follow the parent-child relationship defined in the ACORD AL3 standard. A child group cannot appear without its parent.
2. Field Validation
- Required Fields: Fields marked as
Mandatory (M)in the schema must be present and non-empty. - Type Safety:
- Numeric fields must contain valid digits (or sign characters).
- Date fields must form valid calendar dates (e.g.
20250230is invalid).
- Length: Values must fit within the defined fixed width.
- Generation: Values exceeding the length will cause a validation error.
- Formatting: Short values are automatically padded (zeros for numeric/dates, spaces for text).
3. Logic & Totals
- 1MTG Validation: The
Message Trailercontains the total character count (Length) of the transaction. Integra validates that the parsed message length matches this value to ensure no data was truncated.
Version: 1.0.0
Last Updated: 2026-02-01