{
  "openapi": "3.1.0",
  "info": {
    "title": "Lab API",
    "version": "1.0.0",
    "description": "A browser-only demo API that uses entirely invented data."
  },
  "paths": {
    "/v1/rates/quote": {
      "post": {
        "operationId": "quote-rates",
        "summary": "Quote shipment rates",
        "description": "Returns eligible carrier options sorted from cheapest to most expensive.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "country",
                  "postcode",
                  "weightKg",
                  "parcels",
                  "delivery"
                ],
                "properties": {
                  "country": {
                    "type": "string",
                    "pattern": "^[A-Z]{2}$",
                    "examples": [
                      "ES"
                    ]
                  },
                  "postcode": {
                    "type": "string",
                    "minLength": 1
                  },
                  "weightKg": {
                    "type": "number",
                    "exclusiveMinimum": 0
                  },
                  "parcels": {
                    "type": "integer",
                    "minimum": 1
                  },
                  "delivery": {
                    "type": "string",
                    "enum": [
                      "home",
                      "pickup"
                    ]
                  }
                }
              },
              "example": {
                "country": "ES",
                "postcode": "28013",
                "weightKg": 2.4,
                "parcels": 1,
                "delivery": "home"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Malformed request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/shipments/book": {
      "post": {
        "operationId": "book-shipment",
        "summary": "Book a shipment",
        "description": "Quotes a shipment and tries carriers in price order, falling back after network errors.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "shipment",
                  "failures"
                ],
                "properties": {
                  "shipment": {
                    "type": "object",
                    "additionalProperties": false,
                    "required": [
                      "country",
                      "postcode",
                      "weightKg",
                      "parcels",
                      "delivery"
                    ],
                    "properties": {
                      "country": {
                        "type": "string",
                        "pattern": "^[A-Z]{2}$",
                        "examples": [
                          "ES"
                        ]
                      },
                      "postcode": {
                        "type": "string",
                        "minLength": 1
                      },
                      "weightKg": {
                        "type": "number",
                        "exclusiveMinimum": 0
                      },
                      "parcels": {
                        "type": "integer",
                        "minimum": 1
                      },
                      "delivery": {
                        "type": "string",
                        "enum": [
                          "home",
                          "pickup"
                        ]
                      }
                    }
                  },
                  "failures": {
                    "type": "object",
                    "additionalProperties": {
                      "type": "string",
                      "enum": [
                        "network",
                        "validation"
                      ]
                    }
                  }
                }
              },
              "example": {
                "shipment": {
                  "country": "ES",
                  "postcode": "28013",
                  "weightKg": 2.4,
                  "parcels": 1,
                  "delivery": "home"
                },
                "failures": {
                  "Rayo Express": "network"
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Malformed request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/epc/decode": {
      "post": {
        "operationId": "decode-epc",
        "summary": "Decode an SGTIN-96 EPC",
        "description": "Decodes a 24-character SGTIN-96 hexadecimal value into GS1 fields and URIs.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "hex"
                ],
                "properties": {
                  "hex": {
                    "type": "string",
                    "minLength": 24,
                    "maxLength": 24
                  }
                }
              },
              "example": {
                "hex": "3074257BF7194E4000001A85"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Malformed request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/epc/encode": {
      "post": {
        "operationId": "encode-epc",
        "summary": "Encode an SGTIN-96 EPC",
        "description": "Validates GS1 input and encodes it as a 96-bit hexadecimal EPC.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "gtin",
                  "companyPrefixLength",
                  "filter",
                  "serial"
                ],
                "properties": {
                  "gtin": {
                    "type": "string",
                    "pattern": "^\\d{13,14}$"
                  },
                  "companyPrefixLength": {
                    "type": "integer",
                    "minimum": 6,
                    "maximum": 12
                  },
                  "filter": {
                    "type": "integer",
                    "minimum": 0,
                    "maximum": 7
                  },
                  "serial": {
                    "oneOf": [
                      {
                        "type": "string",
                        "pattern": "^\\d+$"
                      },
                      {
                        "type": "integer",
                        "minimum": 0
                      }
                    ]
                  }
                }
              },
              "example": {
                "gtin": "80614141123458",
                "companyPrefixLength": 7,
                "filter": 3,
                "serial": "6789"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Malformed request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/sql/check": {
      "post": {
        "operationId": "check-sql",
        "summary": "Check read-only SQL",
        "description": "Runs every guardrail layer. A blocked query is a successful check with allowed set to false.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "sql"
                ],
                "properties": {
                  "sql": {
                    "type": "string",
                    "minLength": 1
                  },
                  "maxRows": {
                    "type": "integer",
                    "minimum": 1
                  }
                }
              },
              "example": {
                "sql": "SELECT status, COUNT(*) FROM orders GROUP BY status",
                "maxRows": 100
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Malformed request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    },
    "/v1/pii/mask": {
      "post": {
        "operationId": "mask-pii",
        "summary": "Mask PII in rows",
        "description": "Returns a masked copy of row data and the number of values or fragments masked.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "additionalProperties": false,
                "required": [
                  "rows"
                ],
                "properties": {
                  "rows": {
                    "type": "array",
                    "items": {
                      "type": "object",
                      "additionalProperties": true
                    }
                  }
                }
              },
              "example": {
                "rows": [
                  {
                    "order_id": "ORD-1001",
                    "email": "alba@example.test",
                    "status": "packed",
                    "notes": "Call +34 612 345 678 before delivery."
                  },
                  {
                    "order_id": "ORD-1002",
                    "customer": {
                      "full_name": "Bruno Sol",
                      "loyalty_level": "silver"
                    },
                    "notes": "{\"contact\":\"cora@fiction.test\",\"window\":\"morning\"}"
                  },
                  {
                    "order_id": "ORD-1003",
                    "payment_note": "Refund to ES91 2100 0418 4502 0005 1332",
                    "tags": [
                      "priority",
                      "phone 934567812"
                    ]
                  }
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Successful response.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object"
                }
              }
            }
          },
          "400": {
            "description": "Malformed request.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          },
          "422": {
            "description": "Validation failed.",
            "content": {
              "application/problem+json": {
                "schema": {
                  "$ref": "#/components/schemas/Problem"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Problem": {
        "type": "object",
        "required": [
          "type",
          "title",
          "status",
          "detail"
        ],
        "properties": {
          "type": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "status": {
            "type": "integer"
          },
          "detail": {
            "type": "string"
          },
          "errors": {
            "type": "array",
            "items": {
              "type": "object",
              "required": [
                "field",
                "message"
              ],
              "properties": {
                "field": {
                  "type": "string"
                },
                "message": {
                  "type": "string"
                }
              }
            }
          }
        }
      }
    }
  }
}