{
  "openapi": "3.1.0",
  "info": {
    "title": "Localisync Delivery Protocol",
    "version": "1.0.0",
    "description": "Public read-only protocol. Internal mTLS deployment controls are separate and not public management operations."
  },
  "paths": {
    "/delivery/v1/distributions/{id}/channels/{channel}/manifest": {
      "get": {
        "operationId": "getDeliveryChannel",
        "summary": "Read a signed channel catalog",
        "description": "Distribution and channel-scoped bearer key required. Verify Ed25519 signatures, monotonic catalog revision, immutable manifest digest and file hashes. No management dependencies. Files use private immutable caching; channel manifests require revalidation.",
        "security": [
          {
            "readKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "channel",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "preview",
                "production"
              ]
            }
          },
          {
            "name": "If-None-Match",
            "in": "header",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Verified content.",
            "content": {
              "application/jose": {
                "schema": {
                  "$ref": "#/components/schemas/SignedDocument"
                }
              }
            },
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "304": {
            "description": "The authorized channel revision has not changed."
          },
          "400": {
            "description": "Invalid path or request."
          },
          "401": {
            "description": "Invalid key, channel scope or web origin."
          },
          "404": {
            "description": "Not published or no accessible immutable release."
          },
          "429": {
            "description": "Request rate limit exceeded."
          },
          "500": {
            "description": "Unexpected delivery failure; X-Request-ID identifies the safe event."
          },
          "503": {
            "description": "Local storage or dependency unavailable; X-Request-ID identifies the safe event."
          }
        }
      }
    },
    "/delivery/v1/distributions/{id}/channels/{channel}/releases/{releaseId}/manifest": {
      "get": {
        "operationId": "getDeliveryRelease",
        "summary": "Read a signed immutable release manifest",
        "description": "Distribution and channel-scoped bearer key required. Verify Ed25519 signatures, monotonic catalog revision, immutable manifest digest and file hashes. No management dependencies. Files use private immutable caching; channel manifests require revalidation.",
        "security": [
          {
            "readKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "channel",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "preview",
                "production"
              ]
            }
          },
          {
            "name": "releaseId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Verified content.",
            "content": {
              "application/jose": {
                "schema": {
                  "$ref": "#/components/schemas/SignedDocument"
                }
              }
            },
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Invalid path or request."
          },
          "401": {
            "description": "Invalid key, channel scope or web origin."
          },
          "404": {
            "description": "Not published or no accessible immutable release."
          },
          "429": {
            "description": "Request rate limit exceeded."
          },
          "500": {
            "description": "Unexpected delivery failure; X-Request-ID identifies the safe event."
          },
          "503": {
            "description": "Local storage or dependency unavailable; X-Request-ID identifies the safe event."
          }
        }
      }
    },
    "/delivery/v1/distributions/{id}/channels/{channel}/releases/{releaseId}/files/{hash}": {
      "get": {
        "operationId": "getDeliveryFile",
        "summary": "Download a verified locale file",
        "description": "Distribution and channel-scoped bearer key required. Verify Ed25519 signatures, monotonic catalog revision, immutable manifest digest and file hashes. No management dependencies. Files use private immutable caching; channel manifests require revalidation.",
        "security": [
          {
            "readKey": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "channel",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "enum": [
                "preview",
                "production"
              ]
            }
          },
          {
            "name": "releaseId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "format": "uuid"
            }
          },
          {
            "name": "hash",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string",
              "pattern": "^[a-f0-9]{64}$"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Verified content.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/LocaleFile"
                }
              }
            },
            "headers": {
              "ETag": {
                "schema": {
                  "type": "string"
                }
              }
            }
          },
          "400": {
            "description": "Invalid path or request."
          },
          "401": {
            "description": "Invalid key, channel scope or web origin."
          },
          "404": {
            "description": "Not published or no accessible immutable release."
          },
          "429": {
            "description": "Request rate limit exceeded."
          },
          "500": {
            "description": "Unexpected delivery failure; X-Request-ID identifies the safe event."
          },
          "503": {
            "description": "Local storage or dependency unavailable; X-Request-ID identifies the safe event."
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "SignedDocument": {
        "type": "string",
        "description": "Compact JWS with alg EdDSA, trusted kid and typ localisync+json. UTF-8 JSON payload follows the corresponding manifest schema."
      },
      "ReleaseManifest": {
        "type": "object",
        "properties": {
          "protocol": {
            "type": "number",
            "const": 1
          },
          "kind": {
            "type": "string",
            "const": "release"
          },
          "projectId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "releaseId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "compatibility": {
            "type": "object",
            "properties": {
              "min": {
                "anyOf": [
                  {
                    "type": "string",
                    "maxLength": 256
                  },
                  {
                    "type": "null"
                  }
                ]
              },
              "max": {
                "anyOf": [
                  {
                    "type": "string",
                    "maxLength": 256
                  },
                  {
                    "type": "null"
                  }
                ]
              }
            },
            "required": [
              "min",
              "max"
            ],
            "additionalProperties": false
          },
          "requestedLocales": {
            "minItems": 1,
            "type": "array",
            "items": {
              "type": "string",
              "minLength": 1,
              "maxLength": 255,
              "pattern": "^[A-Za-z0-9-]+$"
            }
          },
          "languages": {
            "minItems": 1,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "locale": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 255,
                  "pattern": "^[A-Za-z0-9-]+$"
                },
                "fallback": {
                  "anyOf": [
                    {
                      "type": "string",
                      "minLength": 1,
                      "maxLength": 255,
                      "pattern": "^[A-Za-z0-9-]+$"
                    },
                    {
                      "type": "null"
                    }
                  ]
                }
              },
              "required": [
                "locale",
                "fallback"
              ],
              "additionalProperties": false
            }
          },
          "files": {
            "minItems": 1,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "locale": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 255,
                  "pattern": "^[A-Za-z0-9-]+$"
                },
                "digest": {
                  "type": "string",
                  "pattern": "^[a-f0-9]{64}$"
                },
                "bytes": {
                  "type": "integer",
                  "exclusiveMinimum": 0,
                  "maximum": 104857600
                }
              },
              "required": [
                "locale",
                "digest",
                "bytes"
              ],
              "additionalProperties": false
            }
          },
          "keyCount": {
            "type": "integer",
            "exclusiveMinimum": 0,
            "maximum": 10000
          }
        },
        "required": [
          "protocol",
          "kind",
          "projectId",
          "releaseId",
          "compatibility",
          "requestedLocales",
          "languages",
          "files",
          "keyCount"
        ],
        "additionalProperties": false
      },
      "ChannelManifest": {
        "type": "object",
        "properties": {
          "protocol": {
            "type": "number",
            "const": 1
          },
          "kind": {
            "type": "string",
            "const": "catalog"
          },
          "projectId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "distributionId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "channel": {
            "type": "string",
            "enum": [
              "preview",
              "production"
            ]
          },
          "revision": {
            "type": "integer",
            "minimum": 0,
            "maximum": 9007199254740991
          },
          "publications": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "releaseId": {
                  "type": "string",
                  "format": "uuid",
                  "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
                },
                "manifestDigest": {
                  "type": "string",
                  "pattern": "^[a-f0-9]{64}$"
                },
                "sequence": {
                  "type": "integer",
                  "exclusiveMinimum": 0,
                  "maximum": 9007199254740991
                },
                "compatibility": {
                  "type": "object",
                  "properties": {
                    "min": {
                      "anyOf": [
                        {
                          "type": "string",
                          "maxLength": 256
                        },
                        {
                          "type": "null"
                        }
                      ]
                    },
                    "max": {
                      "anyOf": [
                        {
                          "type": "string",
                          "maxLength": 256
                        },
                        {
                          "type": "null"
                        }
                      ]
                    }
                  },
                  "required": [
                    "min",
                    "max"
                  ],
                  "additionalProperties": false
                }
              },
              "required": [
                "id",
                "releaseId",
                "manifestDigest",
                "sequence",
                "compatibility"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "protocol",
          "kind",
          "projectId",
          "distributionId",
          "channel",
          "revision",
          "publications"
        ],
        "additionalProperties": false
      },
      "LocaleFile": {
        "type": "object",
        "properties": {
          "protocol": {
            "type": "number",
            "const": 1
          },
          "releaseId": {
            "type": "string",
            "format": "uuid",
            "pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
          },
          "locale": {
            "type": "string",
            "minLength": 1,
            "maxLength": 255,
            "pattern": "^[A-Za-z0-9-]+$"
          },
          "entries": {
            "maxItems": 10000,
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "key": {
                  "type": "string",
                  "minLength": 1,
                  "maxLength": 200
                },
                "format": {
                  "type": "string",
                  "enum": [
                    "plain",
                    "icu"
                  ]
                },
                "parameters": {
                  "maxItems": 32,
                  "type": "array",
                  "items": {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "string",
                        "maxLength": 100,
                        "pattern": "^[A-Za-z_][A-Za-z0-9_]*$"
                      },
                      "type": {
                        "type": "string",
                        "enum": [
                          "text",
                          "number"
                        ]
                      }
                    },
                    "required": [
                      "name",
                      "type"
                    ],
                    "additionalProperties": false
                  }
                },
                "value": {
                  "type": [
                    "string",
                    "null"
                  ]
                }
              },
              "required": [
                "key",
                "format",
                "parameters",
                "value"
              ],
              "additionalProperties": false
            }
          }
        },
        "required": [
          "protocol",
          "releaseId",
          "locale",
          "entries"
        ],
        "additionalProperties": false
      }
    },
    "securitySchemes": {
      "readKey": {
        "type": "http",
        "scheme": "bearer",
        "description": "A distribution and channel-scoped read key. Never send it in a URL."
      }
    }
  }
}
