{
  "openapi": "3.0.3",
  "info": {
    "title": "A8PRO CR local API",
    "version": "1.1.30.0-R4",
    "description": "Source-verified contract for Universal R4. Device and receiving application require acceptance testing. Loopback only; not a browser/public-cloud API. Empty error bodies must be handled. No real client data in examples."
  },
  "servers": [
    {
      "url": "http://localhost:9010"
    }
  ],
  "security": [
    {
      "LocalToken": []
    }
  ],
  "paths": {
    "/v2/status": {
      "get": {
        "operationId": "getStatus",
        "summary": "CHIP presence and feature permissions, not proof of MRZ hardware readiness.",
        "responses": {
          "401": {
            "description": "Token missing or invalid; empty body."
          },
          "403": {
            "description": "License or local access restriction. Body can be empty.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Route or matching scanId not found; empty body."
          },
          "405": {
            "description": "Unsupported method; empty body."
          },
          "429": {
            "description": "Busy. Body can be empty.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal reader_error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Read timeout, reader failure, stopping or overload. Body can be empty.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "200": {
            "description": "Status",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Status"
                },
                "example": {
                  "reader": true,
                  "card": false,
                  "presenceError": false,
                  "autoMode": false,
                  "mrzEnabled": true,
                  "autoModeSample": "before_status_probe",
                  "autoCompletedCount": 0,
                  "lastAutoCompletedUtc": null
                }
              }
            }
          }
        }
      }
    },
    "/v2/getInfo": {
      "get": {
        "operationId": "readDocument",
        "summary": "Starts a new read; NOT idempotent. Serialize reads. Device budget 10 seconds.",
        "responses": {
          "401": {
            "description": "Token missing or invalid; empty body."
          },
          "403": {
            "description": "License or local access restriction. Body can be empty.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Route or matching scanId not found; empty body."
          },
          "405": {
            "description": "Unsupported method; empty body."
          },
          "429": {
            "description": "Busy. Body can be empty.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal reader_error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Read timeout, reader failure, stopping or overload. Body can be empty.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "200": {
            "description": "Fields or waiting; 200 alone does not mean success.",
            "content": {
              "application/json": {
                "schema": {
                  "oneOf": [
                    {
                      "$ref": "#/components/schemas/Person"
                    },
                    {
                      "$ref": "#/components/schemas/Waiting"
                    }
                  ]
                },
                "examples": {
                  "fields": {
                    "value": {
                      "docType": "",
                      "docnum": "TEST-ONLY",
                      "lname": "ПРИМЕР",
                      "fname": "ТЕСТ",
                      "sname": "",
                      "mrzfn": "TEST",
                      "mrzln": "EXAMPLE",
                      "bdate": "01.01.1990",
                      "citizen": "",
                      "iin": "",
                      "issuecountry": "",
                      "issuer": "",
                      "valid_from": "01.01.2025",
                      "valid_to": "01.01.2030",
                      "sex": "",
                      "bplace": "",
                      "nation": "",
                      "photo": "",
                      "sig_photo": ""
                    }
                  },
                  "waiting": {
                    "value": {
                      "status": "waiting",
                      "message": "Поднесите документ к считывателю"
                    }
                  }
                }
              }
            },
            "headers": {
              "X-A8PRO-Scan-Id": {
                "description": "Only on successful fresh read.",
                "schema": {
                  "type": "string"
                }
              },
              "X-A8PRO-Scan-Source": {
                "description": "Only on successful fresh read.",
                "schema": {
                  "type": "string"
                }
              },
              "X-A8PRO-Scanned-At": {
                "description": "Only on successful fresh read.",
                "schema": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    },
    "/v2/getInfo/last": {
      "get": {
        "operationId": "getLast",
        "summary": "One shared process-local result. Replaced by next success. Two-minute expiry checked lazily. Match a known scanId.",
        "responses": {
          "401": {
            "description": "Token missing or invalid; empty body."
          },
          "403": {
            "description": "License or local access restriction. Body can be empty.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Route or matching scanId not found; empty body."
          },
          "405": {
            "description": "Unsupported method; empty body."
          },
          "429": {
            "description": "Busy. Body can be empty.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal reader_error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Read timeout, reader failure, stopping or overload. Body can be empty.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "200": {
            "description": "Cached result",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Last"
                },
                "example": {
                  "scanId": "11111111111111111111111111111111",
                  "scannedAt": "2026-11-05T08:00:00.0000000Z",
                  "source": "chip",
                  "data": {
                    "docType": "",
                    "docnum": "TEST-ONLY",
                    "lname": "ПРИМЕР",
                    "fname": "ТЕСТ",
                    "sname": "",
                    "mrzfn": "TEST",
                    "mrzln": "EXAMPLE",
                    "bdate": "01.01.1990",
                    "citizen": "",
                    "iin": "",
                    "issuecountry": "",
                    "issuer": "",
                    "valid_from": "01.01.2025",
                    "valid_to": "01.01.2030",
                    "sex": "",
                    "bplace": "",
                    "nation": "",
                    "photo": "",
                    "sig_photo": ""
                  }
                }
              }
            }
          },
          "204": {
            "description": "No result; empty body."
          }
        }
      }
    },
    "/v2/getInfo/ack": {
      "post": {
        "operationId": "acknowledge",
        "summary": "Clear matching cached result only AFTER durable save. Repeat can return 404.",
        "responses": {
          "401": {
            "description": "Token missing or invalid; empty body."
          },
          "403": {
            "description": "License or local access restriction. Body can be empty.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Route or matching scanId not found; empty body."
          },
          "405": {
            "description": "Unsupported method; empty body."
          },
          "429": {
            "description": "Busy. Body can be empty.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "500": {
            "description": "Internal reader_error.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "503": {
            "description": "Read timeout, reader failure, stopping or overload. Body can be empty.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "204": {
            "description": "Matching result cleared; empty body."
          }
        },
        "parameters": [
          {
            "name": "scanId",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-f0-9]{32}$"
            }
          }
        ]
      }
    }
  },
  "components": {
    "securitySchemes": {
      "LocalToken": {
        "type": "apiKey",
        "in": "header",
        "name": "X-A8PRO-Token"
      }
    },
    "schemas": {
      "Person": {
        "type": "object",
        "required": [
          "docType",
          "docnum",
          "lname",
          "fname",
          "sname",
          "mrzfn",
          "mrzln",
          "bdate",
          "citizen",
          "iin",
          "issuecountry",
          "issuer",
          "valid_from",
          "valid_to",
          "sex",
          "bplace",
          "nation",
          "photo",
          "sig_photo"
        ],
        "properties": {
          "docType": {
            "type": "string"
          },
          "docnum": {
            "type": "string"
          },
          "lname": {
            "type": "string"
          },
          "fname": {
            "type": "string"
          },
          "sname": {
            "type": "string"
          },
          "mrzfn": {
            "type": "string"
          },
          "mrzln": {
            "type": "string"
          },
          "bdate": {
            "type": "string"
          },
          "citizen": {
            "type": "string"
          },
          "iin": {
            "type": "string"
          },
          "issuecountry": {
            "type": "string"
          },
          "issuer": {
            "type": "string"
          },
          "valid_from": {
            "type": "string"
          },
          "valid_to": {
            "type": "string"
          },
          "sex": {
            "type": "string"
          },
          "bplace": {
            "type": "string"
          },
          "nation": {
            "type": "string"
          },
          "photo": {
            "type": "string"
          },
          "sig_photo": {
            "type": "string"
          }
        }
      },
      "Waiting": {
        "type": "object",
        "required": [
          "status",
          "message"
        ],
        "properties": {
          "status": {
            "type": "string",
            "enum": [
              "waiting"
            ]
          },
          "message": {
            "type": "string"
          },
          "mrzEnabled": {
            "type": "boolean"
          }
        }
      },
      "Error": {
        "type": "object",
        "required": [
          "status"
        ],
        "properties": {
          "status": {
            "type": "string"
          }
        }
      },
      "Status": {
        "type": "object",
        "required": [
          "reader",
          "card",
          "presenceError",
          "autoMode",
          "mrzEnabled",
          "autoModeSample",
          "autoCompletedCount",
          "lastAutoCompletedUtc"
        ],
        "properties": {
          "reader": {
            "type": "boolean"
          },
          "card": {
            "type": "boolean"
          },
          "presenceError": {
            "type": "boolean"
          },
          "autoMode": {
            "type": "boolean"
          },
          "mrzEnabled": {
            "type": "boolean"
          },
          "autoModeSample": {
            "type": "string"
          },
          "autoCompletedCount": {
            "type": "integer"
          },
          "lastAutoCompletedUtc": {
            "type": "string",
            "nullable": true,
            "format": "date-time"
          }
        }
      },
      "Last": {
        "type": "object",
        "required": [
          "scanId",
          "scannedAt",
          "source",
          "data"
        ],
        "properties": {
          "scanId": {
            "type": "string",
            "pattern": "^[a-f0-9]{32}$"
          },
          "scannedAt": {
            "type": "string",
            "format": "date-time"
          },
          "source": {
            "type": "string",
            "enum": [
              "chip",
              "mrz"
            ]
          },
          "data": {
            "$ref": "#/components/schemas/Person"
          }
        }
      }
    }
  }
}
