{
  "openapi": "3.1.0",
  "info": {
    "title": "DucDZ Public APIs",
    "version": "1.0.0",
    "description": "Contract công khai cho Email API và Download API của DucDZ. Email là hộp thư tạm công khai; không dùng cho dữ liệu nhạy cảm."
  },
  "externalDocs": {
    "description": "Tài liệu và quickstart",
    "url": "https://docs.anhduc.tech/"
  },
  "tags": [
    { "name": "Email", "description": "Hộp thư tạm, attachment và realtime SSE" },
    { "name": "Download", "description": "Metadata, job tải và file media tạm" }
  ],
  "paths": {
    "/v1/email/random": {
      "get": {
        "operationId": "createRandomEmailAddress",
        "summary": "Sinh địa chỉ email ngẫu nhiên",
        "tags": ["Email"],
        "servers": [{ "url": "https://api.anhduc.tech" }],
        "security": [],
        "parameters": [
          {
            "name": "domain",
            "in": "query",
            "required": false,
            "schema": { "type": "string", "enum": ["anhduc.tech", "duc.baby"], "default": "anhduc.tech" }
          }
        ],
        "responses": {
          "200": {
            "description": "Địa chỉ vừa sinh",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["address", "domain", "domains"],
                  "properties": {
                    "address": { "type": "string", "format": "email" },
                    "domain": { "type": "string" },
                    "domains": { "type": "array", "items": { "type": "string" } }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/EmailError" },
          "429": { "$ref": "#/components/responses/EmailError" }
        }
      }
    },
    "/v1/email/inbox/{address}": {
      "get": {
        "operationId": "listEmailInbox",
        "summary": "Liệt kê email theo cursor",
        "tags": ["Email"],
        "servers": [{ "url": "https://api.anhduc.tech" }],
        "security": [],
        "parameters": [
          { "$ref": "#/components/parameters/EmailAddress" },
          { "name": "limit", "in": "query", "schema": { "type": "integer", "minimum": 1, "maximum": 100, "default": 50 } },
          { "name": "folder", "in": "query", "schema": { "type": "string", "enum": ["inbox", "spam"], "default": "inbox" } },
          { "name": "before", "in": "query", "description": "next_cursor từ trang trước", "schema": { "type": "string", "pattern": "^[1-9][0-9]*$" } }
        ],
        "responses": {
          "200": {
            "description": "Một trang inbox",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["mailbox", "folder", "count", "emails", "next_cursor"],
                  "properties": {
                    "mailbox": { "type": "string", "format": "email" },
                    "folder": { "type": "string", "enum": ["inbox", "spam"] },
                    "count": { "type": "integer", "minimum": 0 },
                    "emails": { "type": "array", "items": { "$ref": "#/components/schemas/EmailSummary" } },
                    "next_cursor": { "type": ["string", "null"] }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/EmailError" },
          "403": { "$ref": "#/components/responses/EmailError" },
          "429": { "$ref": "#/components/responses/EmailError" }
        }
      }
    },
    "/v1/email/message/{id}": {
      "get": {
        "operationId": "getEmailMessage",
        "summary": "Đọc nội dung đầy đủ của email",
        "tags": ["Email"],
        "servers": [{ "url": "https://api.anhduc.tech" }],
        "security": [],
        "parameters": [{ "$ref": "#/components/parameters/NumericId" }],
        "responses": {
          "200": {
            "description": "Email cùng body đã sanitize và attachment",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EmailMessage" } } }
          },
          "400": { "$ref": "#/components/responses/EmailError" },
          "403": { "$ref": "#/components/responses/EmailError" },
          "404": { "$ref": "#/components/responses/EmailError" },
          "429": { "$ref": "#/components/responses/EmailError" }
        }
      }
    },
    "/v1/email/attachment/{id}": {
      "get": {
        "operationId": "downloadEmailAttachment",
        "summary": "Tải attachment",
        "tags": ["Email"],
        "servers": [{ "url": "https://api.anhduc.tech" }],
        "security": [],
        "parameters": [{ "$ref": "#/components/parameters/NumericId" }],
        "responses": {
          "200": {
            "description": "Nội dung binary của attachment",
            "headers": {
              "Content-Disposition": { "schema": { "type": "string" } },
              "Content-Length": { "schema": { "type": "integer" } }
            },
            "content": { "application/octet-stream": { "schema": { "type": "string", "format": "binary" } } }
          },
          "400": { "$ref": "#/components/responses/EmailError" },
          "403": { "$ref": "#/components/responses/EmailError" },
          "404": { "$ref": "#/components/responses/EmailError" },
          "429": { "$ref": "#/components/responses/EmailError" }
        }
      }
    },
    "/v1/email/stream/{address}": {
      "get": {
        "operationId": "streamEmailInbox",
        "summary": "Subscribe inbox bằng Server-Sent Events",
        "tags": ["Email"],
        "servers": [{ "url": "https://api.anhduc.tech" }],
        "security": [],
        "parameters": [{ "$ref": "#/components/parameters/EmailAddress" }],
        "responses": {
          "200": {
            "description": "SSE stream gồm event ready và message; heartbeat là comment",
            "content": { "text/event-stream": { "schema": { "type": "string" } } }
          },
          "400": { "$ref": "#/components/responses/EmailError" },
          "403": { "$ref": "#/components/responses/EmailError" },
          "429": { "$ref": "#/components/responses/EmailError" }
        }
      }
    },
    "/v1/email/send": {
      "post": {
        "operationId": "sendEmail",
        "summary": "Gửi email nội bộ hoặc direct MX",
        "tags": ["Email"],
        "servers": [{ "url": "https://api.anhduc.tech" }],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": { "$ref": "#/components/schemas/SendEmailRequest" }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Kết quả delivery",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SendEmailResponse" } } }
          },
          "400": { "$ref": "#/components/responses/EmailError" },
          "403": { "$ref": "#/components/responses/EmailError" },
          "413": { "$ref": "#/components/responses/EmailError" },
          "429": { "$ref": "#/components/responses/EmailError" },
          "502": { "$ref": "#/components/responses/EmailError" }
        }
      }
    },
    "/api/info": {
      "post": {
        "operationId": "getMediaInfo",
        "summary": "Đọc metadata và các format tải được",
        "tags": ["Download"],
        "servers": [{ "url": "https://video.anhduc.tech" }],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["url"],
                "properties": { "url": { "type": "string", "description": "URL hoặc share text chứa URL đầu tiên", "maxLength": 8192 } }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Metadata media",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["ok", "info"],
                  "properties": {
                    "ok": { "const": true },
                    "cached": { "type": "boolean" },
                    "info": { "$ref": "#/components/schemas/MediaInfo" }
                  }
                }
              }
            }
          },
          "400": { "$ref": "#/components/responses/DownloadError" },
          "422": { "$ref": "#/components/responses/DownloadError" },
          "429": { "$ref": "#/components/responses/DownloadError" }
        }
      }
    },
    "/api/download": {
      "post": {
        "operationId": "createDownloadJob",
        "summary": "Tạo job tải",
        "tags": ["Download"],
        "servers": [{ "url": "https://video.anhduc.tech" }],
        "security": [],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": ["url", "optionId"],
                "properties": {
                  "url": { "type": "string" },
                  "optionId": { "type": "string", "pattern": "^(video-(\\d{2,4}|best)|audio-mp3-(128|192|320)|audio-m4a|photos-(zip|mp4)|photo-\\d{1,3})$" }
                }
              }
            }
          }
        },
        "responses": {
          "202": {
            "description": "Job đã được xếp hàng",
            "content": { "application/json": { "schema": { "$ref": "#/components/schemas/JobEnvelope" } } }
          },
          "400": { "$ref": "#/components/responses/DownloadError" },
          "401": { "$ref": "#/components/responses/DownloadError" },
          "422": { "$ref": "#/components/responses/DownloadError" },
          "429": { "$ref": "#/components/responses/DownloadError" }
        }
      }
    },
    "/api/status/{id}": {
      "get": {
        "operationId": "getDownloadJob",
        "summary": "Đọc trạng thái job",
        "tags": ["Download"],
        "servers": [{ "url": "https://video.anhduc.tech" }],
        "security": [],
        "parameters": [{ "$ref": "#/components/parameters/JobId" }],
        "responses": {
          "200": { "description": "Trạng thái hiện tại", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/JobEnvelope" } } } },
          "400": { "$ref": "#/components/responses/DownloadError" },
          "404": { "$ref": "#/components/responses/DownloadError" }
        }
      }
    },
    "/api/cancel/{id}": {
      "post": {
        "operationId": "cancelDownloadJob",
        "summary": "Huỷ job chưa kết thúc",
        "tags": ["Download"],
        "servers": [{ "url": "https://video.anhduc.tech" }],
        "security": [],
        "parameters": [{ "$ref": "#/components/parameters/JobId" }],
        "responses": {
          "200": {
            "description": "Đã huỷ",
            "content": { "application/json": { "schema": { "type": "object", "required": ["ok"], "properties": { "ok": { "const": true } } } } }
          },
          "400": { "$ref": "#/components/responses/DownloadError" },
          "401": { "$ref": "#/components/responses/DownloadError" },
          "409": { "$ref": "#/components/responses/DownloadError" }
        }
      }
    },
    "/api/file/{id}": {
      "get": {
        "operationId": "downloadMediaFile",
        "summary": "Tải file của job đã hoàn tất",
        "tags": ["Download"],
        "servers": [{ "url": "https://video.anhduc.tech" }],
        "security": [],
        "parameters": [
          { "$ref": "#/components/parameters/JobId" },
          { "name": "Range", "in": "header", "schema": { "type": "string", "examples": ["bytes=0-1048575"] } }
        ],
        "responses": {
          "200": { "description": "File đầy đủ", "content": { "application/octet-stream": { "schema": { "type": "string", "format": "binary" } } } },
          "206": { "description": "Một byte range", "content": { "application/octet-stream": { "schema": { "type": "string", "format": "binary" } } } },
          "302": { "description": "Redirect tới presigned R2 URL", "headers": { "Location": { "schema": { "type": "string", "format": "uri" } } } },
          "400": { "$ref": "#/components/responses/DownloadError" },
          "404": { "$ref": "#/components/responses/DownloadError" },
          "409": { "$ref": "#/components/responses/DownloadError" },
          "416": { "description": "Range ngoài kích thước file" }
        }
      },
      "head": {
        "operationId": "headMediaFile",
        "summary": "Đọc header file",
        "tags": ["Download"],
        "servers": [{ "url": "https://video.anhduc.tech" }],
        "security": [],
        "parameters": [{ "$ref": "#/components/parameters/JobId" }],
        "responses": { "200": { "description": "Header file" }, "302": { "description": "Redirect tới R2" } }
      }
    },
    "/api/health": {
      "get": {
        "operationId": "getDownloadHealth",
        "summary": "Kiểm tra readiness và queue",
        "tags": ["Download"],
        "servers": [{ "url": "https://video.anhduc.tech" }],
        "security": [],
        "responses": {
          "200": {
            "description": "Trạng thái public",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["ok", "status", "engine", "queue"],
                  "properties": {
                    "ok": { "const": true },
                    "status": { "type": "string", "enum": ["ready", "degraded"] },
                    "engine": {
                      "type": "object",
                      "required": ["ytdlp", "ffmpeg", "javascript"],
                      "properties": {
                        "ytdlp": { "type": "boolean" },
                        "ffmpeg": { "type": "boolean" },
                        "javascript": { "type": "boolean" }
                      }
                    },
                    "queue": {
                      "type": "object",
                      "required": ["running", "queued"],
                      "properties": { "running": { "type": "integer" }, "queued": { "type": "integer" } }
                    }
                  }
                }
              }
            }
          }
        }
      }
    },
    "/api/platforms": {
      "get": {
        "operationId": "listDownloadPlatforms",
        "summary": "Liệt kê nền tảng public tại runtime",
        "tags": ["Download"],
        "servers": [{ "url": "https://video.anhduc.tech" }],
        "security": [],
        "responses": {
          "200": {
            "description": "Danh sách nền tảng",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "required": ["ok", "platforms"],
                  "properties": {
                    "ok": { "const": true },
                    "platforms": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "required": ["id", "name", "status"],
                        "properties": {
                          "id": { "type": "string" },
                          "name": { "type": "string" },
                          "status": { "type": "string", "enum": ["supported", "limited"] }
                        }
                      }
                    }
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "parameters": {
      "EmailAddress": {
        "name": "address",
        "in": "path",
        "required": true,
        "schema": { "type": "string", "format": "email" }
      },
      "NumericId": {
        "name": "id",
        "in": "path",
        "required": true,
        "schema": { "type": "integer", "minimum": 1 }
      },
      "JobId": {
        "name": "id",
        "in": "path",
        "required": true,
        "schema": { "type": "string", "pattern": "^[a-f0-9]{18}$" }
      }
    },
    "responses": {
      "EmailError": {
        "description": "Email API error",
        "headers": { "X-Request-Id": { "schema": { "type": "string" } } },
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EmailError" } } }
      },
      "DownloadError": {
        "description": "Download API error",
        "content": { "application/json": { "schema": { "$ref": "#/components/schemas/DownloadError" } } }
      }
    },
    "schemas": {
      "EmailSummary": {
        "type": "object",
        "required": ["id", "mailbox", "from", "from_addr", "sender", "subject", "received_at", "is_read", "is_starred"],
        "properties": {
          "id": { "type": "integer" },
          "mailbox": { "type": "string", "format": "email" },
          "from": { "type": "string" },
          "from_addr": { "type": "string", "format": "email" },
          "sender": { "type": "string" },
          "subject": { "type": "string" },
          "received_at": { "type": "string" },
          "is_read": { "type": "boolean" },
          "is_starred": { "type": "boolean" }
        }
      },
      "EmailMessage": {
        "allOf": [
          { "$ref": "#/components/schemas/EmailSummary" },
          {
            "type": "object",
            "required": ["body_text", "body_html", "reply_to", "attachments"],
            "properties": {
              "body_text": { "type": "string" },
              "body_html": { "type": "string", "description": "Sanitized HTML" },
              "reply_to": { "type": "string" },
              "attachments": { "type": "array", "items": { "$ref": "#/components/schemas/EmailAttachment" } }
            }
          }
        ]
      },
      "EmailAttachment": {
        "type": "object",
        "required": ["id", "filename", "mime", "size", "download_url"],
        "properties": {
          "id": { "type": "integer" },
          "filename": { "type": "string" },
          "mime": { "type": "string" },
          "size": { "type": "integer", "minimum": 0 },
          "download_url": { "type": "string" }
        }
      },
      "SendEmailRequest": {
        "type": "object",
        "required": ["from", "to"],
        "anyOf": [{ "required": ["text"] }, { "required": ["html"] }],
        "properties": {
          "from": { "type": "string", "format": "email" },
          "to": { "type": "string", "format": "email" },
          "subject": { "type": "string", "maxLength": 500 },
          "text": { "type": "string" },
          "html": { "type": "string" },
          "inReplyTo": { "type": "string", "maxLength": 998 },
          "references": { "type": "string", "maxLength": 4000 }
        }
      },
      "SendEmailResponse": {
        "type": "object",
        "required": ["ok", "delivery", "messageId"],
        "properties": {
          "ok": { "const": true },
          "delivery": { "type": "string", "enum": ["internal", "external"] },
          "id": { "type": "integer" },
          "messageId": { "type": "string" },
          "accepted": { "type": "array", "items": { "type": "string" } },
          "rejected": { "type": "array", "items": { "type": "string" } }
        }
      },
      "EmailError": {
        "type": "object",
        "required": ["error", "code", "request_id"],
        "properties": {
          "error": { "type": "string" },
          "code": { "type": "string" },
          "request_id": { "type": "string" },
          "retry_after": { "type": "integer", "minimum": 1 }
        }
      },
      "DownloadError": {
        "type": "object",
        "required": ["ok", "error"],
        "properties": { "ok": { "const": false }, "error": { "type": "string" } }
      },
      "MediaOption": {
        "type": "object",
        "required": ["id", "label", "ext"],
        "properties": {
          "id": { "type": "string" },
          "label": { "type": "string" },
          "ext": { "type": "string" },
          "quality": { "type": "integer" },
          "size": { "type": ["integer", "null"] }
        }
      },
      "MediaInfo": {
        "type": "object",
        "required": ["title", "platform", "options"],
        "properties": {
          "title": { "type": "string" },
          "platform": { "type": "string" },
          "platformName": { "type": "string" },
          "duration": { "type": ["number", "null"] },
          "durationText": { "type": ["string", "null"] },
          "thumbnail": { "type": ["string", "null"], "format": "uri" },
          "audioOnly": { "type": "boolean" },
          "photoPost": { "type": "boolean" },
          "imageCount": { "type": "integer", "minimum": 0 },
          "options": {
            "type": "object",
            "required": ["video", "audio"],
            "properties": {
              "video": { "type": "array", "items": { "$ref": "#/components/schemas/MediaOption" } },
              "audio": { "type": "array", "items": { "$ref": "#/components/schemas/MediaOption" } }
            }
          }
        }
      },
      "DownloadJob": {
        "type": "object",
        "required": ["id", "status", "percent"],
        "properties": {
          "id": { "type": "string", "pattern": "^[a-f0-9]{18}$" },
          "status": { "type": "string", "enum": ["queued", "downloading", "processing", "done", "error", "cancelled"] },
          "percent": { "type": "number", "minimum": 0, "maximum": 100 },
          "speed": { "type": ["string", "null"] },
          "eta": { "type": ["string", "null"] },
          "filename": { "type": ["string", "null"] },
          "size": { "type": ["integer", "null"] },
          "sizeText": { "type": ["string", "null"] },
          "downloadUrl": { "type": ["string", "null"] },
          "error": { "type": ["string", "null"] }
        }
      },
      "JobEnvelope": {
        "type": "object",
        "required": ["ok", "job"],
        "properties": { "ok": { "const": true }, "job": { "$ref": "#/components/schemas/DownloadJob" } }
      }
    }
  }
}
