{
  "openapi": "3.1.0",
  "info": {
    "title": "ASCII Art Converter API",
    "description": "Public browser-local image-to-ASCII support, chroma-aware color exports, server conversion previews, chunked large artifact manifests, MCP introspection, Web Status, and protected webhook/handoff actions for ascii.platphormnews.com.",
    "version": "1.0.0",
    "contact": {
      "name": "Michael Barbine",
      "email": "Michael@Barbineworldwide.com",
      "url": "https://github.com/mbarbine/image-to-ascii-webby"
    },
    "license": {
      "name": "MIT",
      "url": "https://opensource.org/licenses/MIT"
    }
  },
  "servers": [
    {
      "url": "https://ascii.platphormnews.com",
      "description": "Production"
    }
  ],
  "tags": [
    {
      "name": "conversion",
      "description": "Image to ASCII conversion"
    },
    {
      "name": "artifacts",
      "description": "Temporary ASCII artifact manifests, chunks, and exports"
    },
    {
      "name": "charsets",
      "description": "ASCII character set catalog"
    },
    {
      "name": "health",
      "description": "Health and platform contract status"
    },
    {
      "name": "web-status",
      "description": "Web Status and readiness scorecards"
    },
    {
      "name": "mcp",
      "description": "Model Context Protocol JSON-RPC 2.0 endpoint"
    },
    {
      "name": "webhooks",
      "description": "Protected webhook subscription actions"
    },
    {
      "name": "discovery",
      "description": "Public discovery files and trust policy"
    },
    {
      "name": "docs",
      "description": "API documentation"
    }
  ],
  "components": {
    "securitySchemes": {
      "PlatPhormApiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-PlatPhorm-API-Key",
        "description": "Protected actions accept X-PlatPhorm-API-Key: $PLATPHORM_API_KEY or Authorization: Bearer $PLATPHORM_API_KEY."
      },
      "PlatPhormBearer": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "PLATPHORM_API_KEY"
      }
    }
  },
  "paths": {
    "/api/convert": {
      "post": {
        "operationId": "convertImage",
        "tags": [
          "conversion"
        ],
        "summary": "Convert an inline image or trusted artifact URL to ASCII text or a chunked artifact preview",
        "description": "Public-safe conversion endpoint. Raw uploaded image bytes are decoded for conversion only and are not persisted. Trusted *.platphormnews.com and Vercel Blob image artifact URLs can convert without PLATPHORM_API_KEY; untrusted external artifact URLs require PLATPHORM_API_KEY. When grayscale is false, ASCII text stays compact while responses include exact source hex color grids and compact chroma sidecar metadata for per-character color references. Large ASCII output returns preview, artifact manifest, chunk links, hashes, and continuation metadata instead of failing at the legacy 2 MB output size.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "image": {
                    "type": "string",
                    "description": "Base64 image data or data URI."
                  },
                  "imageUrl": {
                    "type": "string",
                    "description": "Trusted PlatPhorm/Vercel Blob image artifact URL or authenticated external image URL."
                  },
                  "artifactUrl": {
                    "type": "string",
                    "description": "Trusted BrowserOps/AgentUI/Docs artifact URL or authenticated external image URL."
                  },
                  "resolution": {
                    "type": "number",
                    "minimum": 0.05,
                    "maximum": 1,
                    "default": 0.11
                  },
                  "width": {
                    "type": "number",
                    "description": "Requested ASCII output columns before runtime guardrails."
                  },
                  "chunkLineCount": {
                    "type": "number",
                    "default": 80
                  },
                  "artifactMode": {
                    "type": "string",
                    "enum": [
                      "none",
                      "auto",
                      "force"
                    ],
                    "default": "auto"
                  },
                  "charset": {
                    "type": "string",
                    "enum": [
                      "standard",
                      "detailed",
                      "blocks",
                      "minimal",
                      "binary",
                      "matrix"
                    ],
                    "default": "standard"
                  },
                  "grayscale": {
                    "type": "boolean",
                    "default": true
                  },
                  "inverted": {
                    "type": "boolean",
                    "default": false
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "ASCII conversion result using the standard REST envelope."
          },
          "400": {
            "description": "Invalid image, unsupported type, or runtime guardrail violation."
          },
          "503": {
            "description": "Conversion runtime unavailable."
          }
        }
      }
    },
    "/api/convert/chunked": {
      "post": {
        "operationId": "convertImageChunked",
        "tags": [
          "conversion",
          "artifacts"
        ],
        "summary": "Convert an image into a temporary chunked ASCII artifact",
        "description": "Forces artifact manifest creation. Useful for BrowserOps screenshots, Evals packets, AgentUI blocks, Docs report packets, and output that should be navigated by chunks.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Chunked conversion result with artifact manifest and inline first chunks."
          },
          "400": {
            "description": "Invalid image, unsupported type, or runtime guardrail violation."
          },
          "503": {
            "description": "Conversion runtime unavailable."
          }
        }
      }
    },
    "/api/convert/url": {
      "post": {
        "operationId": "convertImageUrl",
        "tags": [
          "conversion",
          "artifacts"
        ],
        "summary": "Convert a trusted image artifact URL to ASCII without a key, or an untrusted external URL with PLATPHORM_API_KEY",
        "description": "Trusted *.platphormnews.com and Vercel Blob image artifact URLs convert without PLATPHORM_API_KEY. Untrusted external artifact URLs require PLATPHORM_API_KEY and still pass SSRF/size/type guardrails.",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Conversion result, chunked artifact result, or input-required state."
          },
          "400": {
            "description": "Invalid or unsafe artifact URL."
          },
          "401": {
            "description": "PLATPHORM_API_KEY required for untrusted external artifact URL fetches."
          },
          "415": {
            "description": "Artifact did not return a supported image content type."
          }
        }
      }
    },
    "/api/convert/stream": {
      "post": {
        "operationId": "streamImageConversion",
        "tags": [
          "conversion",
          "artifacts"
        ],
        "summary": "Convert an image and return NDJSON manifest/chunk records",
        "description": "Returns application/x-ndjson with a manifest record, chunk records, and a completed record. The conversion still uses real image decoding and chunk content; it does not return fake stream events.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "NDJSON conversion stream."
          },
          "400": {
            "description": "Invalid image, unsupported type, or runtime guardrail violation."
          },
          "503": {
            "description": "Conversion runtime unavailable."
          }
        }
      }
    },
    "/api/convert/browserops": {
      "post": {
        "operationId": "convertBrowserOpsScreenshot",
        "tags": [
          "conversion",
          "artifacts"
        ],
        "summary": "Convert a trusted BrowserOps screenshot artifact URL or inline payload",
        "description": "Trusted *.platphormnews.com and Vercel Blob image artifact URLs convert without PLATPHORM_API_KEY. Untrusted external artifact URLs require PLATPHORM_API_KEY and still pass SSRF/size/type guardrails.",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Conversion result, chunked artifact result, or input-required state."
          },
          "400": {
            "description": "Invalid or unsafe artifact URL."
          },
          "401": {
            "description": "PLATPHORM_API_KEY required for untrusted external artifact URL fetches."
          },
          "415": {
            "description": "Artifact did not return a supported image content type."
          }
        }
      }
    },
    "/api/convert/agentui": {
      "post": {
        "operationId": "convertAgentUiWorkflowArtifact",
        "tags": [
          "conversion",
          "artifacts"
        ],
        "summary": "Convert a trusted AgentUI workflow image artifact URL or inline payload",
        "description": "Trusted *.platphormnews.com and Vercel Blob image artifact URLs convert without PLATPHORM_API_KEY. Untrusted external artifact URLs require PLATPHORM_API_KEY and still pass SSRF/size/type guardrails.",
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Conversion result, chunked artifact result, or input-required state."
          },
          "400": {
            "description": "Invalid or unsafe artifact URL."
          },
          "401": {
            "description": "PLATPHORM_API_KEY required for untrusted external artifact URL fetches."
          },
          "415": {
            "description": "Artifact did not return a supported image content type."
          }
        }
      }
    },
    "/api/convert/docs": {
      "post": {
        "operationId": "publishConversionToDocs",
        "tags": [
          "conversion",
          "artifacts"
        ],
        "summary": "Request Docs publication for an ASCII artifact",
        "security": [
          {
            "PlatPhormApiKey": []
          },
          {
            "PlatPhormBearer": []
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Protected action result or honest degraded state."
          },
          "401": {
            "description": "PLATPHORM_API_KEY required."
          }
        }
      }
    },
    "/api/convert/evals": {
      "post": {
        "operationId": "sendConversionToEvals",
        "tags": [
          "conversion",
          "artifacts"
        ],
        "summary": "Request Evals evidence packet creation for an ASCII artifact",
        "security": [
          {
            "PlatPhormApiKey": []
          },
          {
            "PlatPhormBearer": []
          }
        ],
        "requestBody": {
          "required": false,
          "content": {
            "application/json": {
              "schema": {
                "type": "object"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Protected action result or honest degraded state."
          },
          "401": {
            "description": "PLATPHORM_API_KEY required."
          }
        }
      }
    },
    "/api/ascii/status": {
      "get": {
        "operationId": "getAsciiStatus",
        "tags": [
          "health",
          "web-status"
        ],
        "summary": "Get ASCII capability, storage, and Web Status metadata",
        "responses": {
          "200": {
            "description": "ASCII runtime status."
          }
        }
      }
    },
    "/api/ascii/storage/status": {
      "get": {
        "operationId": "getAsciiStorageStatus",
        "tags": [
          "health",
          "artifacts"
        ],
        "summary": "Get storage and large artifact runtime status",
        "responses": {
          "200": {
            "description": "Storage status payload."
          }
        }
      }
    },
    "/api/artifacts": {
      "get": {
        "operationId": "listArtifacts",
        "tags": [
          "artifacts"
        ],
        "summary": "List temporary ASCII artifacts in this runtime",
        "responses": {
          "200": {
            "description": "Public-safe temporary artifact list."
          }
        }
      }
    },
    "/api/artifacts/{id}": {
      "get": {
        "operationId": "getArtifact",
        "tags": [
          "artifacts"
        ],
        "summary": "Get one temporary ASCII artifact",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Get one temporary ASCII artifact"
          },
          "404": {
            "description": "Artifact not found or expired."
          }
        }
      }
    },
    "/api/artifacts/{id}/manifest": {
      "get": {
        "operationId": "getArtifactManifest",
        "tags": [
          "artifacts"
        ],
        "summary": "Get one ASCII artifact manifest",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Get one ASCII artifact manifest"
          },
          "404": {
            "description": "Artifact not found or expired."
          }
        }
      }
    },
    "/api/artifacts/{id}/chunks": {
      "get": {
        "operationId": "getArtifactChunks",
        "tags": [
          "artifacts"
        ],
        "summary": "List ASCII artifact chunks",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "List ASCII artifact chunks"
          },
          "404": {
            "description": "Artifact not found or expired."
          }
        }
      }
    },
    "/api/artifacts/{id}/chunks/{chunkId}": {
      "get": {
        "operationId": "getArtifactChunk",
        "tags": [
          "artifacts"
        ],
        "summary": "Get one ASCII artifact chunk",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "chunkId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Chunk content and hash."
          },
          "404": {
            "description": "Chunk not found or expired."
          }
        }
      }
    },
    "/api/artifacts/{id}/preview": {
      "get": {
        "operationId": "getArtifactPreview",
        "tags": [
          "artifacts"
        ],
        "summary": "Get artifact preview text",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Get artifact preview text"
          },
          "404": {
            "description": "Artifact not found or expired."
          }
        }
      }
    },
    "/api/artifacts/{id}/download.txt": {
      "get": {
        "operationId": "downloadArtifactText",
        "tags": [
          "artifacts"
        ],
        "summary": "Download ASCII text",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Download ASCII text"
          },
          "404": {
            "description": "Artifact not found or expired."
          }
        }
      }
    },
    "/api/artifacts/{id}/download.md": {
      "get": {
        "operationId": "downloadArtifactMarkdown",
        "tags": [
          "artifacts"
        ],
        "summary": "Download Markdown export",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Download Markdown export"
          },
          "404": {
            "description": "Artifact not found or expired."
          }
        }
      }
    },
    "/api/artifacts/{id}/download.html": {
      "get": {
        "operationId": "downloadArtifactHtml",
        "tags": [
          "artifacts"
        ],
        "summary": "Download HTML export",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Download HTML export"
          },
          "404": {
            "description": "Artifact not found or expired."
          }
        }
      }
    },
    "/api/artifacts/{id}/download.svg": {
      "get": {
        "operationId": "downloadArtifactSvg",
        "tags": [
          "artifacts"
        ],
        "summary": "Download SVG export",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Download SVG export"
          },
          "404": {
            "description": "Artifact not found or expired."
          }
        }
      }
    },
    "/api/artifacts/{id}/download.json": {
      "get": {
        "operationId": "downloadArtifactJson",
        "tags": [
          "artifacts"
        ],
        "summary": "Download JSON artifact package",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Download JSON artifact package"
          },
          "404": {
            "description": "Artifact not found or expired."
          }
        }
      }
    },
    "/api/artifacts/{id}/download.ndjson": {
      "get": {
        "operationId": "downloadArtifactNdjson",
        "tags": [
          "artifacts"
        ],
        "summary": "Download NDJSON artifact package",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Download NDJSON artifact package"
          },
          "404": {
            "description": "Artifact not found or expired."
          }
        }
      }
    },
    "/api/artifacts/{id}/publish/docs": {
      "post": {
        "operationId": "publishArtifactToDocs",
        "tags": [
          "artifacts"
        ],
        "summary": "Request Docs publication for an ASCII artifact",
        "security": [
          {
            "PlatPhormApiKey": []
          },
          {
            "PlatPhormBearer": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Protected artifact action result or honest degraded state."
          },
          "401": {
            "description": "PLATPHORM_API_KEY required."
          }
        }
      }
    },
    "/api/artifacts/{id}/send/agentui": {
      "post": {
        "operationId": "sendArtifactToAgentUi",
        "tags": [
          "artifacts"
        ],
        "summary": "Request AgentUI handoff for an ASCII artifact",
        "security": [
          {
            "PlatPhormApiKey": []
          },
          {
            "PlatPhormBearer": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Protected artifact action result or honest degraded state."
          },
          "401": {
            "description": "PLATPHORM_API_KEY required."
          }
        }
      }
    },
    "/api/artifacts/{id}/send/evals": {
      "post": {
        "operationId": "sendArtifactToEvals",
        "tags": [
          "artifacts"
        ],
        "summary": "Request Evals evidence packet creation for an ASCII artifact",
        "security": [
          {
            "PlatPhormApiKey": []
          },
          {
            "PlatPhormBearer": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Protected artifact action result or honest degraded state."
          },
          "401": {
            "description": "PLATPHORM_API_KEY required."
          }
        }
      }
    },
    "/api/web/status": {
      "get": {
        "operationId": "getWebStatus",
        "tags": [
          "web-status"
        ],
        "summary": "Get Web Status",
        "responses": {
          "200": {
            "description": "Get Web Status response."
          }
        }
      }
    },
    "/api/web/scorecard": {
      "get": {
        "operationId": "getWebScorecard",
        "tags": [
          "web-status"
        ],
        "summary": "Get Web Status scorecard",
        "responses": {
          "200": {
            "description": "Get Web Status scorecard response."
          }
        }
      }
    },
    "/api/web/manifest": {
      "get": {
        "operationId": "getWebManifest",
        "tags": [
          "web-status"
        ],
        "summary": "Get Web manifest",
        "responses": {
          "200": {
            "description": "Get Web manifest response."
          }
        }
      }
    },
    "/api/web/fingerprints": {
      "get": {
        "operationId": "getWebFingerprints",
        "tags": [
          "web-status"
        ],
        "summary": "Get deterministic Web fingerprints",
        "responses": {
          "200": {
            "description": "Get deterministic Web fingerprints response."
          }
        }
      }
    },
    "/api/v1/charsets": {
      "get": {
        "operationId": "listCharsets",
        "tags": [
          "charsets"
        ],
        "summary": "List active ASCII character sets",
        "responses": {
          "200": {
            "description": "Charset list."
          }
        }
      }
    },
    "/api/v1/info": {
      "get": {
        "operationId": "getInfo",
        "tags": [
          "discovery"
        ],
        "summary": "Get public service metadata",
        "responses": {
          "200": {
            "description": "Public metadata."
          }
        }
      }
    },
    "/api/health": {
      "get": {
        "operationId": "getHealth",
        "tags": [
          "health"
        ],
        "summary": "Get service health and platform contract status",
        "responses": {
          "200": {
            "description": "Health payload using standard REST envelope."
          }
        }
      }
    },
    "/api/v1/health": {
      "get": {
        "operationId": "getHealth",
        "tags": [
          "health"
        ],
        "summary": "Get service health and platform contract status",
        "responses": {
          "200": {
            "description": "Health payload using standard REST envelope."
          }
        }
      }
    },
    "/api/webhooks": {
      "get": {
        "operationId": "listWebhooks",
        "tags": [
          "webhooks"
        ],
        "summary": "List public-safe webhook subscription status",
        "responses": {
          "200": {
            "description": "Public-safe webhook list with URLs redacted unless authenticated."
          }
        }
      },
      "post": {
        "operationId": "subscribeWebhook",
        "tags": [
          "webhooks"
        ],
        "summary": "Subscribe a webhook",
        "security": [
          {
            "PlatPhormApiKey": []
          },
          {
            "PlatPhormBearer": []
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "url"
                ],
                "properties": {
                  "url": {
                    "type": "string",
                    "format": "uri"
                  },
                  "events": {
                    "type": "array",
                    "items": {
                      "type": "string",
                      "enum": [
                        "conversion.started",
                        "conversion.completed",
                        "conversion.failed",
                        "health.degraded",
                        "health.restored"
                      ]
                    }
                  },
                  "secret": {
                    "type": "string",
                    "description": "Optional HMAC secret. Never returned in public responses."
                  }
                }
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Webhook registered in available storage."
          },
          "401": {
            "description": "PLATPHORM_API_KEY required."
          }
        }
      },
      "delete": {
        "operationId": "deleteWebhookByQuery",
        "tags": [
          "webhooks"
        ],
        "summary": "Delete a webhook by query id",
        "security": [
          {
            "PlatPhormApiKey": []
          },
          {
            "PlatPhormBearer": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook deleted."
          },
          "401": {
            "description": "PLATPHORM_API_KEY required."
          },
          "404": {
            "description": "Webhook not found."
          }
        }
      }
    },
    "/api/webhooks/{id}": {
      "delete": {
        "operationId": "deleteWebhook",
        "tags": [
          "webhooks"
        ],
        "summary": "Delete a webhook by id",
        "security": [
          {
            "PlatPhormApiKey": []
          },
          {
            "PlatPhormBearer": []
          }
        ],
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Webhook deleted."
          },
          "401": {
            "description": "PLATPHORM_API_KEY required."
          },
          "404": {
            "description": "Webhook not found."
          }
        }
      }
    },
    "/api/v1/webhooks/test": {
      "post": {
        "operationId": "testWebhook",
        "tags": [
          "webhooks"
        ],
        "summary": "Run a protected webhook test or return honest degraded dispatch state",
        "security": [
          {
            "PlatPhormApiKey": []
          },
          {
            "PlatPhormBearer": []
          }
        ],
        "responses": {
          "200": {
            "description": "Test result."
          },
          "401": {
            "description": "PLATPHORM_API_KEY required."
          }
        }
      }
    },
    "/api/mcp": {
      "get": {
        "operationId": "getMcpMetadata",
        "tags": [
          "mcp"
        ],
        "summary": "Get MCP metadata and usage",
        "responses": {
          "200": {
            "description": "MCP server metadata."
          }
        }
      },
      "post": {
        "operationId": "postMcpJsonRpc",
        "tags": [
          "mcp"
        ],
        "summary": "MCP JSON-RPC 2.0 endpoint",
        "description": "Supports initialize, ping, tools/list, tools/call, resources/list, resources/read, prompts/list, and prompts/get. Protected tools require PLATPHORM_API_KEY on the HTTP request.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "required": [
                  "method"
                ],
                "properties": {
                  "jsonrpc": {
                    "type": "string",
                    "const": "2.0"
                  },
                  "id": {
                    "type": [
                      "string",
                      "number",
                      "null"
                    ]
                  },
                  "method": {
                    "type": "string",
                    "enum": [
                      "initialize",
                      "ping",
                      "tools/list",
                      "tools/call",
                      "resources/list",
                      "resources/read",
                      "prompts/list",
                      "prompts/get"
                    ]
                  },
                  "params": {
                    "type": "object",
                    "properties": {
                      "name": {
                        "type": "string",
                        "enum": [
                          "convert_image",
                          "get_ascii_info",
                          "get_ascii_status",
                          "get_web_status",
                          "get_conversion_capabilities",
                          "estimate_ascii_output",
                          "convert_image_to_ascii_preview",
                          "convert_image_url_to_ascii_preview",
                          "convert_large_image_to_ascii_manifest",
                          "list_ascii_artifacts",
                          "get_ascii_artifact",
                          "get_ascii_artifact_manifest",
                          "get_ascii_artifact_chunks",
                          "get_ascii_chunk",
                          "list_charsets",
                          "get_charset",
                          "get_info",
                          "get_health",
                          "subscribe_webhook",
                          "list_webhooks",
                          "delete_webhook",
                          "test_webhook",
                          "get_route_compliance",
                          "get_discovery_compliance",
                          "create_docs_report",
                          "create_sheet_report",
                          "create_deck_summary",
                          "convert_image_to_ascii_stream",
                          "convert_browserops_screenshot_to_ascii",
                          "publish_ascii_artifact_to_docs",
                          "send_ascii_artifact_to_agentui",
                          "send_ascii_artifact_to_evals",
                          "save_as_png"
                        ]
                      },
                      "uri": {
                        "type": "string",
                        "enum": [
                          "ascii://capabilities",
                          "ascii://charsets",
                          "ascii://charset/{slug}",
                          "ascii://info",
                          "ascii://status",
                          "ascii://examples",
                          "ascii://artifacts",
                          "ascii://artifact/{id}",
                          "ascii://artifact/{id}/manifest",
                          "ascii://artifact/{id}/chunks",
                          "ascii://webhooks",
                          "ascii://openapi",
                          "ascii://llms",
                          "ascii://web-status",
                          "ascii://agent-policy",
                          "ascii://trust-policy"
                        ]
                      },
                      "arguments": {
                        "type": "object"
                      }
                    }
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "JSON-RPC result or batch result."
          }
        }
      }
    },
    "/openapi.yaml": {
      "get": {
        "operationId": "getOpenApiYaml",
        "tags": [
          "discovery"
        ],
        "summary": "OpenAPI spec",
        "responses": {
          "200": {
            "description": "OpenAPI YAML."
          }
        }
      }
    },
    "/openapi.json": {
      "get": {
        "operationId": "getOpenApiJson",
        "tags": [
          "discovery"
        ],
        "summary": "OpenAPI JSON spec",
        "responses": {
          "200": {
            "description": "OpenAPI JSON."
          }
        }
      }
    }
  },
  "webhooks": {
    "conversionEvent": {
      "post": {
        "summary": "Conversion event notification",
        "description": "Webhook payload shape for conversion and health events. Dispatch is protected and honestly degraded when no delivery backend is configured."
      }
    }
  },
  "externalDocs": {
    "description": "PlatPhormNews MCP hub docs",
    "url": "https://mcp.platphormnews.com/api/docs"
  },
  "x-mcp-hub": {
    "url": "https://mcp.platphormnews.com",
    "docs": "https://mcp.platphormnews.com/api/docs",
    "description": "Central MCP capability registry for the PlatPhormNews network."
  },
  "x-platform": {
    "service": "ascii-converter",
    "publicAccess": true,
    "protectedActions": [
      "POST /api/webhooks",
      "DELETE /api/webhooks",
      "DELETE /api/webhooks/{id}",
      "POST /api/v1/webhooks/test",
      "Untrusted external image artifact URL fetches",
      "POST /api/convert/docs",
      "POST /api/convert/evals",
      "POST /api/artifacts/{id}/publish/docs",
      "POST /api/artifacts/{id}/send/agentui",
      "POST /api/artifacts/{id}/send/evals",
      "MCP subscribe_webhook",
      "MCP delete_webhook",
      "MCP test_webhook",
      "MCP untrusted external image artifact URL fetches",
      "MCP publish_ascii_artifact_to_docs",
      "MCP send_ascii_artifact_to_agentui",
      "MCP send_ascii_artifact_to_evals",
      "MCP create_docs_report",
      "MCP create_sheet_report",
      "MCP create_deck_summary"
    ],
    "webStatus": "https://ascii.platphormnews.com/api/web/status",
    "noHard2mbLimit": true,
    "tools": [
      "convert_image",
      "get_ascii_info",
      "get_ascii_status",
      "get_web_status",
      "get_conversion_capabilities",
      "estimate_ascii_output",
      "convert_image_to_ascii_preview",
      "convert_image_url_to_ascii_preview",
      "convert_large_image_to_ascii_manifest",
      "list_ascii_artifacts",
      "get_ascii_artifact",
      "get_ascii_artifact_manifest",
      "get_ascii_artifact_chunks",
      "get_ascii_chunk",
      "list_charsets",
      "get_charset",
      "get_info",
      "get_health",
      "subscribe_webhook",
      "list_webhooks",
      "delete_webhook",
      "test_webhook",
      "get_route_compliance",
      "get_discovery_compliance",
      "create_docs_report",
      "create_sheet_report",
      "create_deck_summary",
      "convert_image_to_ascii_stream",
      "convert_browserops_screenshot_to_ascii",
      "publish_ascii_artifact_to_docs",
      "send_ascii_artifact_to_agentui",
      "send_ascii_artifact_to_evals",
      "save_as_png"
    ],
    "resources": [
      "ascii://capabilities",
      "ascii://charsets",
      "ascii://charset/{slug}",
      "ascii://info",
      "ascii://status",
      "ascii://examples",
      "ascii://artifacts",
      "ascii://artifact/{id}",
      "ascii://artifact/{id}/manifest",
      "ascii://artifact/{id}/chunks",
      "ascii://webhooks",
      "ascii://openapi",
      "ascii://llms",
      "ascii://web-status",
      "ascii://agent-policy",
      "ascii://trust-policy"
    ],
    "prompts": [
      "convert_image_to_ascii",
      "convert_screenshot_to_ascii",
      "convert_browserops_artifact",
      "create_ascii_docs_report",
      "create_agentui_ascii_block",
      "create_evals_ascii_packet",
      "explain_ascii_settings",
      "generate_ascii_style_recommendation",
      "create_ascii_export_plan",
      "debug_ascii_conversion",
      "debug_large_ascii_conversion",
      "create_ascii_artifact_manifest",
      "human_machine_ascii_handoff"
    ],
    "automationTransports": [
      {
        "id": "rest_sync",
        "label": "REST synchronous conversion",
        "status": "implemented",
        "routes": [
          "/api/convert",
          "/api/convert/url",
          "/api/convert/browserops",
          "/api/convert/agentui"
        ],
        "use": "Small and medium conversions, trusted artifact URL intake, and standard request/response automation."
      },
      {
        "id": "chunked_artifacts",
        "label": "Chunked artifact manifests",
        "status": "implemented",
        "routes": [
          "/api/convert/chunked",
          "/api/artifacts/{id}/manifest",
          "/api/artifacts/{id}/chunks"
        ],
        "use": "Large output, proof artifacts, continuation links, hashes, and export formats."
      },
      {
        "id": "ndjson_stream",
        "label": "NDJSON conversion stream",
        "status": "implemented",
        "routes": [
          "/api/convert/stream"
        ],
        "use": "Line-delimited manifest and chunk records for agents that want progressive reads without SSE."
      },
      {
        "id": "mcp_json_rpc",
        "label": "MCP JSON-RPC tools",
        "status": "implemented",
        "routes": [
          "/api/mcp",
          "/.well-known/mcp.json"
        ],
        "use": "Agent tool calls, resources, prompts, conversion previews, artifact manifests, and public-safe introspection."
      },
      {
        "id": "atom_updates",
        "label": "Atom/RSS update feeds",
        "status": "implemented_for_updates",
        "routes": [
          "/atom.xml",
          "/rss.xml",
          "/feed.xml"
        ],
        "use": "Public change discovery and capability updates. These feeds are not conversion transports."
      },
      {
        "id": "sse",
        "label": "Server-Sent Events",
        "status": "not_implemented_not_required",
        "routes": [],
        "use": "Not needed for current conversion because NDJSON streaming, chunk manifests, and MCP cover automation needs."
      },
      {
        "id": "async_jobs",
        "label": "Async queued conversion jobs",
        "status": "planned",
        "routes": [],
        "use": "Future durable jobs for long-running, persisted, or multi-step conversions once durable storage is configured."
      }
    ]
  }
}