{
  "openapi": "3.1.0",
  "info": {
    "title": "FENKI Neural Kit API",
    "version": "1.1.0",
    "description": "Builds versioned, provenance-aware artifacts for foundation models. Astrology values returned by this API are authoritative. For an exact chart image, call natal or a single transit moment with format=png or format=svg; do not ask an image model to reconstruct geometry."
  },
  "externalDocs": { "description": "Published FENKI Astrology GPT", "url": "https://chatgpt.com/g/g-6a7c81eb0a0c8191bfa79ed0daab3ed3-fenki-astrology" },
  "servers": [{ "url": "https://fenki.net" }],
  "tags": [{ "name": "astrology", "description": "Deterministic astrology calculations using the registered astrology adapter." }],
  "security": [],
  "paths": {
    "/llm/astrology/natal": {
      "get": {
        "operationId": "calculateAstrologyNatalChart",
        "x-openai-isConsequential": false,
        "tags": ["astrology"],
        "summary": "Calculate a natal chart",
        "description": "Call with format=json first. Save its data.chartRef for transit calls. Specify the location as a place name OR as latitude+longitude with timezone, never both. Returns authoritative positions, houses, aspects, provenance. For an exact image, call renderAstrologyNatalChart instead.",
        "parameters": [
          { "name": "date", "in": "query", "required": true, "description": "Civil birth date in YYYY-MM-DD form.", "schema": { "type": "string", "format": "date" } },
          { "name": "time", "in": "query", "required": true, "description": "Civil birth time in HH:mm or HH:mm:ss form.", "schema": { "type": "string", "example": "11:30" } },
          { "name": "timezone", "in": "query", "required": false, "description": "IANA timezone. Required when coordinates are supplied; inferred from a place name.", "schema": { "type": "string", "example": "Europe/Berlin" } },
          { "name": "latitude", "in": "query", "required": false, "description": "Latitude, used with longitude and timezone when no place name is supplied.", "schema": { "type": "number", "minimum": -90, "maximum": 90 } },
          { "name": "longitude", "in": "query", "required": false, "description": "Longitude, used with latitude and timezone when no place name is supplied.", "schema": { "type": "number", "minimum": -180, "maximum": 180 } },
          { "name": "place", "in": "query", "required": false, "description": "Place name to geocode; coordinates and timezone are inferred. Either this, or latitude+longitude+timezone; do not send both.", "schema": { "type": "string", "example": "Paris, France" } },
          { "name": "label", "in": "query", "required": false, "description": "Human-readable chart label.", "schema": { "type": "string" } },
          { "name": "format", "in": "query", "required": false, "description": "Artifact format; defaults to json.", "schema": { "type": "string", "enum": ["json", "markdown", "compact"], "default": "json" } }
        ],
        "responses": {
          "200": {
            "description": "Canonical natal artifact.",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/FenkiArtifact" } },
              "text/markdown": { "schema": { "type": "string" } },
              "text/plain": { "schema": { "type": "string" } }
            }
          },
          "400": { "$ref": "#/components/responses/Error" }, "404": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/llm/astrology/natal/image": {
      "get": {
        "operationId": "renderAstrologyNatalChart",
        "x-openai-isConsequential": false,
        "tags": ["astrology"],
        "summary": "Render an exact natal chart PNG",
        "description": "Exact PNG of the natal wheel from the same deterministic calculation as calculateAstrologyNatalChart, using identical location inputs (place name, or coordinates plus timezone). Present this image as the chart; never reconstruct geometry.",
        "parameters": [
          { "name": "date", "in": "query", "required": true, "description": "Civil birth date in YYYY-MM-DD form.", "schema": { "type": "string", "format": "date" } },
          { "name": "time", "in": "query", "required": true, "description": "Civil birth time in HH:mm or HH:mm:ss form.", "schema": { "type": "string", "example": "11:30" } },
          { "name": "timezone", "in": "query", "required": false, "description": "IANA timezone. Required when coordinates are supplied; inferred from a place name.", "schema": { "type": "string", "example": "Europe/Berlin" } },
          { "name": "latitude", "in": "query", "required": false, "description": "Latitude, used with longitude and timezone when no place name is supplied.", "schema": { "type": "number", "minimum": -90, "maximum": 90 } },
          { "name": "longitude", "in": "query", "required": false, "description": "Longitude, used with latitude and timezone when no place name is supplied.", "schema": { "type": "number", "minimum": -180, "maximum": 180 } },
          { "name": "place", "in": "query", "required": false, "description": "Place name to geocode; coordinates and timezone are inferred. Either this, or latitude+longitude+timezone; do not send both.", "schema": { "type": "string", "example": "Paris, France" } },
          { "name": "label", "in": "query", "required": false, "description": "Human-readable chart label.", "schema": { "type": "string" } },
          { "name": "embed", "in": "query", "required": false, "description": "Set to base64 to receive the image as JSON with base64 data instead of a binary body. Use this when a browsing sandbox will not open a freshly composed URL.", "schema": { "type": "string", "enum": ["base64"] } }
        ],
        "responses": {
          "200": {
            "description": "Exact natal chart PNG, or JSON with base64 image data when embed=base64.",
            "content": {
              "image/png": { "schema": { "type": "string", "format": "binary", "contentMediaType": "image/png" } },
              "application/json": { "schema": { "$ref": "#/components/schemas/EmbeddedImage" } }
            }
          },
          "400": { "$ref": "#/components/responses/Error" }, "404": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/llm/astrology/natal/image/base64": {
      "get": {
        "operationId": "embedAstrologyNatalChart",
        "x-openai-isConsequential": false,
        "tags": ["astrology"],
        "summary": "Return a natal chart as base64 JSON",
        "description": "Exact natal wheel from the same deterministic calculation as calculateAstrologyNatalChart, using identical location inputs. Returns application/json with imageUrl (present as a markdown image) plus compact base64 SVG by default; format=png gives full-resolution data that can exceed chat limits.",
        "parameters": [
          { "name": "date", "in": "query", "required": true, "description": "Civil birth date in YYYY-MM-DD form.", "schema": { "type": "string", "format": "date" } },
          { "name": "time", "in": "query", "required": true, "description": "Civil birth time in HH:mm or HH:mm:ss form.", "schema": { "type": "string", "example": "11:30" } },
          { "name": "timezone", "in": "query", "required": false, "description": "IANA timezone. Required when coordinates are supplied; inferred from a place name.", "schema": { "type": "string", "example": "Europe/Berlin" } },
          { "name": "latitude", "in": "query", "required": false, "description": "Latitude, used with longitude and timezone when no place name is supplied.", "schema": { "type": "number", "minimum": -90, "maximum": 90 } },
          { "name": "longitude", "in": "query", "required": false, "description": "Longitude, used with latitude and timezone when no place name is supplied.", "schema": { "type": "number", "minimum": -180, "maximum": 180 } },
          { "name": "place", "in": "query", "required": false, "description": "Place name to geocode; coordinates and timezone are inferred. Either this, or latitude+longitude+timezone; do not send both.", "schema": { "type": "string", "example": "Paris, France" } },
          { "name": "label", "in": "query", "required": false, "description": "Human-readable chart label.", "schema": { "type": "string" } },
          { "name": "format", "in": "query", "required": false, "description": "Base64 data format: svg (compact, default) or png (full resolution, may exceed chat response limits).", "schema": { "type": "string", "enum": ["png", "svg"], "default": "svg" } }
        ],
        "responses": {
          "200": {
            "description": "Natal chart as base64 JSON (SVG by default) with imageUrl for full-resolution PNG presentation.",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/EmbeddedImage" } }
            }
          },
          "400": { "$ref": "#/components/responses/Error" }, "404": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/llm/astrology/chart": {
      "get": {
        "operationId": "calculateAstrologyChartAtTime",
        "x-openai-isConsequential": false,
        "tags": ["astrology"],
        "summary": "Calculate the sky at an instant",
        "description": "Calculates a chart for at=now or an ISO 8601 instant. A place name or explicit coordinates are required. Use FENKI values instead of estimating astronomical positions.",
        "parameters": [
          { "name": "at", "in": "query", "required": false, "description": "The literal now or an ISO 8601 instant. Defaults to now.", "schema": { "type": "string", "default": "now" } },
          { "name": "place", "in": "query", "required": false, "description": "Place name to geocode; coordinates and timezone are inferred. Either this or latitude+longitude.", "schema": { "type": "string", "example": "Greenwich" } },
          { "name": "latitude", "in": "query", "required": false, "description": "Latitude, used with longitude when no place name is supplied.", "schema": { "type": "number", "minimum": -90, "maximum": 90 } },
          { "name": "longitude", "in": "query", "required": false, "description": "Longitude, used with latitude when no place name is supplied.", "schema": { "type": "number", "minimum": -180, "maximum": 180 } },
          { "name": "format", "in": "query", "required": false, "description": "Artifact rendering.", "schema": { "type": "string", "enum": ["json", "markdown", "compact"], "default": "json" } }
        ],
        "responses": { "200": { "$ref": "#/components/responses/Artifact" }, "400": { "$ref": "#/components/responses/Error" }, "404": { "$ref": "#/components/responses/Error" } }
      }
    },
    "/llm/astrology/transits": {
      "get": {
        "operationId": "calculateAstrologyNatalTransits",
        "x-openai-isConsequential": false,
        "tags": ["astrology"],
        "summary": "Calculate transits from a natal chartRef",
        "description": "First call calculateAstrologyNatalChart with format=json. Copy only its data.chartRef into chart; never pass a URL, JSON, or constructed value. This returns authoritative directed transit-to-natal aspects. For an exact wheel call renderAstrologyTransitChart.",
        "parameters": [
      { "name": "chart", "in": "query", "required": true, "description": "Required: exact data.chartRef returned by calculateAstrologyNatalChart. Pass only that value, never a URL, JSON artifact, or manually constructed reference. Sensitive.", "schema": { "type": "string" } },
          { "name": "at", "in": "query", "required": false, "description": "The literal now or an ISO 8601 instant. Defaults to now.", "schema": { "type": "string", "default": "now" } },
          { "name": "place", "in": "query", "required": false, "description": "Optional transit place name; natal coordinates are the fallback. Either this or coordinates.", "schema": { "type": "string" } },
          { "name": "latitude", "in": "query", "required": false, "description": "Optional transit latitude, used with longitude when no transit place is supplied.", "schema": { "type": "number", "minimum": -90, "maximum": 90 } },
          { "name": "longitude", "in": "query", "required": false, "description": "Optional transit longitude, used with latitude when no transit place is supplied.", "schema": { "type": "number", "minimum": -180, "maximum": 180 } },
      { "name": "format", "in": "query", "required": false, "description": "Artifact format; defaults to json.", "schema": { "type": "string", "enum": ["json", "markdown", "compact"], "default": "json" } }
        ],
        "responses": {
          "200": {
            "description": "Canonical single-moment transit artifact.",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/FenkiArtifact" } },
              "text/markdown": { "schema": { "type": "string" } },
              "text/plain": { "schema": { "type": "string" } }
            }
          },
          "400": { "$ref": "#/components/responses/Error" }, "404": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/llm/astrology/transits/image": {
      "get": {
        "operationId": "renderAstrologyTransitChart",
        "x-openai-isConsequential": false,
        "tags": ["astrology"],
        "summary": "Render an exact transit chart PNG",
        "description": "Exact PNG of the transit-to-natal wheel from the same deterministic calculation as calculateAstrologyNatalTransits, using the identical chart reference and at. Present this image as the chart; never reconstruct geometry.",
        "parameters": [
          { "name": "chart", "in": "query", "required": true, "description": "Required: exact data.chartRef returned by calculateAstrologyNatalChart. Pass only that value, never a URL, JSON artifact, or manually constructed reference. Sensitive.", "schema": { "type": "string" } },
          { "name": "at", "in": "query", "required": false, "description": "The literal now or an ISO 8601 instant. Defaults to now.", "schema": { "type": "string", "default": "now" } },
          { "name": "place", "in": "query", "required": false, "description": "Optional transit place name; natal coordinates are the fallback. Either this or coordinates.", "schema": { "type": "string" } },
          { "name": "latitude", "in": "query", "required": false, "description": "Optional transit latitude, used with longitude when no transit place is supplied.", "schema": { "type": "number", "minimum": -90, "maximum": 90 } },
          { "name": "longitude", "in": "query", "required": false, "description": "Optional transit longitude, used with latitude when no transit place is supplied.", "schema": { "type": "number", "minimum": -180, "maximum": 180 } },
          { "name": "embed", "in": "query", "required": false, "description": "Set to base64 to receive the image as JSON with base64 data instead of a binary body. Use this when a browsing sandbox will not open a freshly composed URL.", "schema": { "type": "string", "enum": ["base64"] } }
        ],
        "responses": {
          "200": {
            "description": "Exact transit chart PNG, or JSON with base64 image data when embed=base64.",
            "content": {
              "image/png": { "schema": { "type": "string", "format": "binary", "contentMediaType": "image/png" } },
              "application/json": { "schema": { "$ref": "#/components/schemas/EmbeddedImage" } }
            }
          },
          "400": { "$ref": "#/components/responses/Error" }, "404": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/llm/astrology/transits/image/base64": {
      "get": {
        "operationId": "embedAstrologyTransitChart",
        "x-openai-isConsequential": false,
        "tags": ["astrology"],
        "summary": "Return a transit chart as base64 JSON",
        "description": "Exact transit-to-natal wheel from the same calculation as calculateAstrologyNatalTransits, using the identical chart and at. Returns application/json with imageUrl (present as a markdown image) plus compact base64 SVG by default; format=png can exceed chat limits.",
        "parameters": [
          { "name": "chart", "in": "query", "required": true, "description": "Required: exact data.chartRef returned by calculateAstrologyNatalChart. Pass only that value, never a URL, JSON artifact, or manually constructed reference. Sensitive.", "schema": { "type": "string" } },
          { "name": "at", "in": "query", "required": false, "description": "The literal now or an ISO 8601 instant. Defaults to now.", "schema": { "type": "string", "default": "now" } },
          { "name": "place", "in": "query", "required": false, "description": "Optional transit place name; natal coordinates are the fallback. Either this or coordinates.", "schema": { "type": "string" } },
          { "name": "latitude", "in": "query", "required": false, "description": "Optional transit latitude, used with longitude when no transit place is supplied.", "schema": { "type": "number", "minimum": -90, "maximum": 90 } },
          { "name": "longitude", "in": "query", "required": false, "description": "Optional transit longitude, used with latitude when no transit place is supplied.", "schema": { "type": "number", "minimum": -180, "maximum": 180 } },
          { "name": "format", "in": "query", "required": false, "description": "Base64 data format: svg (compact, default) or png (full resolution, may exceed chat response limits).", "schema": { "type": "string", "enum": ["png", "svg"], "default": "svg" } }
        ],
        "responses": {
          "200": {
            "description": "Transit chart as base64 JSON (SVG by default) with imageUrl for full-resolution PNG presentation.",
            "content": {
              "application/json": { "schema": { "$ref": "#/components/schemas/EmbeddedImage" } }
            }
          },
          "400": { "$ref": "#/components/responses/Error" }, "404": { "$ref": "#/components/responses/Error" }
        }
      }
    },
    "/llm/astrology/events": {
      "get": {
        "operationId": "calculateAstrologyTransitRange",
        "x-openai-isConsequential": false,
        "tags": ["astrology"],
        "summary": "Calculate natal transit snapshots over a range",
        "description": "Calculates bounded, inclusive transit snapshots from from through to. Use this for periods instead of choosing arbitrary dates. This operation returns sampled charts and does not claim exact aspect-event detection.",
        "parameters": [
      { "name": "chart", "in": "query", "required": true, "description": "Exact data.chartRef returned by calculateAstrologyNatalChart; never pass a URL, JSON artifact, or constructed value. Sensitive.", "schema": { "type": "string" } },
          { "name": "from", "in": "query", "required": true, "description": "Inclusive ISO 8601 range start.", "schema": { "type": "string", "format": "date-time" } },
          { "name": "to", "in": "query", "required": true, "description": "Inclusive ISO 8601 range end.", "schema": { "type": "string", "format": "date-time" } },
          { "name": "stepHours", "in": "query", "required": false, "description": "Hours between samples; at most 64 samples.", "schema": { "type": "number", "minimum": 0.25, "default": 24 } },
          { "name": "place", "in": "query", "required": false, "description": "Optional transit place name; natal coordinates are the fallback. Either this or coordinates.", "schema": { "type": "string" } },
          { "name": "latitude", "in": "query", "required": false, "description": "Optional transit latitude, used with longitude when no transit place is supplied.", "schema": { "type": "number", "minimum": -90, "maximum": 90 } },
          { "name": "longitude", "in": "query", "required": false, "description": "Optional transit longitude, used with latitude when no transit place is supplied.", "schema": { "type": "number", "minimum": -180, "maximum": 180 } },
          { "name": "format", "in": "query", "required": false, "description": "Artifact rendering. Range image output is not supported.", "schema": { "type": "string", "enum": ["json", "markdown", "compact"], "default": "json" } }
        ],
        "responses": { "200": { "$ref": "#/components/responses/Artifact" }, "400": { "$ref": "#/components/responses/Error" }, "404": { "$ref": "#/components/responses/Error" } }
      }
    }
  },
  "components": {
    "schemas": {
      "FenkiArtifact": {
        "type": "object",
        "required": ["fenki", "type", "adapter", "adapterVersion", "generatedAt", "data"],
        "properties": {
          "fenki": { "type": "string", "const": "1.0.0" },
          "type": { "type": "string", "examples": ["astrology.natal"] },
          "adapter": { "type": "string", "const": "astrology" },
          "adapterVersion": { "type": "string" },
          "generatedAt": { "type": "string", "format": "date-time" },
          "request": { "description": "Normalized operation input." },
          "provenance": { "type": "array", "items": { "type": "object", "additionalProperties": true } },
          "data": {
            "type": "object",
            "required": ["charts"],
            "properties": {
              "charts": { "type": "array", "items": { "$ref": "#/components/schemas/AstrologyDataset" } },
              "chartRef": { "type": "string" },
              "interval": { "type": "object", "additionalProperties": true }
            }
          }
        }
      },
      "AstrologyDataset": {
        "type": "object",
        "required": ["schema", "identity", "provenance", "raw", "derived", "validation"],
        "description": "Canonical calculated astrology dataset. A transit dataset keeps natal positions in raw.astronomy.positions and current positions in raw.astronomy.transitPositions.",
        "properties": {
          "schema": { "type": "object", "required": ["name", "version", "namespace"], "properties": { "name": { "const": "fenki.dataset" }, "version": { "const": "1.0.0" }, "namespace": { "const": "fenki.astro" } } },
          "identity": { "type": "object", "required": ["id", "label", "mode", "createdAt"], "properties": { "id": { "type": "string" }, "label": { "type": "string" }, "mode": { "type": "string", "enum": ["natal", "now", "transit"] }, "createdAt": { "type": "string", "format": "date-time" } } },
          "provenance": { "$ref": "#/components/schemas/ChartProvenance" },
          "raw": { "type": "object", "required": ["astronomy"], "properties": { "astronomy": { "type": "object", "required": ["positions", "houses"], "properties": { "positions": { "type": "array", "items": { "$ref": "#/components/schemas/AstroPosition" } }, "houses": { "$ref": "#/components/schemas/HouseSet" }, "transitPositions": { "type": "array", "items": { "$ref": "#/components/schemas/AstroPosition" } } } } } },
          "derived": { "type": "object", "required": ["astrology"], "properties": { "astrology": { "type": "object", "required": ["positions", "aspects"], "properties": { "positions": { "type": "array", "items": { "$ref": "#/components/schemas/DerivedPosition" } }, "aspects": { "type": "array", "items": { "$ref": "#/components/schemas/AstroAspect" } } } } } },
          "validation": { "type": "object", "required": ["valid", "errors", "warnings"], "properties": { "valid": { "type": "boolean" }, "errors": { "type": "array", "items": { "type": "object", "additionalProperties": true } }, "warnings": { "type": "array", "items": { "type": "object", "additionalProperties": true } } } }
        }
      },
      "ChartInput": {
        "type": "object", "required": ["date", "time", "timezone", "latitude", "longitude"],
        "properties": { "date": { "type": "string", "format": "date" }, "time": { "type": "string" }, "timezone": { "type": "string" }, "latitude": { "type": "number" }, "longitude": { "type": "number" }, "label": { "type": "string" }, "place": { "type": "string" } }
      },
      "ChartProvenance": {
        "type": "object", "required": ["engine", "input", "utc", "julianDay"],
        "properties": { "engine": { "type": "object", "required": ["name", "version", "precision"], "properties": { "name": { "type": "string" }, "version": { "type": "string" }, "precision": { "type": "string" } } }, "input": { "$ref": "#/components/schemas/ChartInput" }, "transitInput": { "$ref": "#/components/schemas/ChartInput" }, "utc": { "type": "string", "format": "date-time" }, "transitUtc": { "type": "string", "format": "date-time" }, "julianDay": { "type": "number" }, "transitJulianDay": { "type": "number" } }
      },
      "AstroPosition": {
        "type": "object", "required": ["body", "longitude", "latitude", "distanceAu", "speedLongitude"],
        "properties": { "body": { "$ref": "#/components/schemas/Body" }, "longitude": { "type": "number", "minimum": 0, "exclusiveMaximum": 360 }, "latitude": { "type": "number" }, "distanceAu": { "type": "number" }, "speedLongitude": { "type": "number" }, "source": { "type": "string", "enum": ["natal", "transit"] } }
      },
      "HouseSet": {
        "type": "object", "required": ["system", "ascendant", "midheaven", "cusps"],
        "properties": { "system": { "const": "placidus" }, "ascendant": { "type": "number" }, "midheaven": { "type": "number" }, "cusps": { "type": "array", "minItems": 12, "maxItems": 12, "items": { "type": "object", "required": ["house", "longitude"], "properties": { "house": { "type": "integer", "minimum": 1, "maximum": 12 }, "longitude": { "type": "number", "minimum": 0, "exclusiveMaximum": 360 } } } } }
      },
      "DerivedPosition": {
        "type": "object", "required": ["body", "longitude", "sign", "signIndex", "degreeInSign", "house", "formatted", "glyph"],
        "properties": { "body": { "$ref": "#/components/schemas/Body" }, "longitude": { "type": "number" }, "sign": { "type": "string" }, "signIndex": { "type": "integer", "minimum": 0, "maximum": 11 }, "degreeInSign": { "type": "number", "minimum": 0, "exclusiveMaximum": 30 }, "house": { "type": "integer", "minimum": 1, "maximum": 12 }, "formatted": { "type": "string" }, "glyph": { "type": "string" } }
      },
      "AstroAspect": {
        "type": "object", "required": ["id", "type", "angle", "orb", "strength", "applying", "scope", "left", "right"],
        "properties": { "id": { "type": "string" }, "type": { "type": "string", "enum": ["conjunction", "opposition", "trine", "square", "sextile"] }, "angle": { "type": "number" }, "orb": { "type": "number" }, "strength": { "type": "number", "minimum": 0, "maximum": 1 }, "applying": { "type": ["boolean", "null"] }, "scope": { "type": "string", "enum": ["natal", "transit_to_natal"] }, "left": { "$ref": "#/components/schemas/AspectEndpoint" }, "right": { "$ref": "#/components/schemas/AspectEndpoint" } }
      },
      "AspectEndpoint": {
        "type": "object", "required": ["body", "source"], "properties": { "body": { "$ref": "#/components/schemas/Body" }, "source": { "type": "string", "enum": ["natal", "transit"] } }
      },
      "Body": {
        "type": "string", "enum": ["sun", "moon", "mercury", "venus", "mars", "jupiter", "saturn", "uranus", "neptune", "pluto"]
      },
      "EmbeddedImage": {
        "type": "object",
        "required": ["format", "mediaType", "imageUrl"],
        "properties": {
          "chartRef": { "type": "string", "description": "Stateless chart reference for follow-up transit calls, when available." },
          "format": { "type": "string", "enum": ["png", "svg"] },
          "mediaType": { "type": "string", "examples": ["image/png", "image/svg+xml"] },
          "encoding": { "const": "base64" },
          "data": { "type": "string", "description": "Base64-encoded image data. The default SVG is compact, but a full-resolution PNG can exceed a chat tool response-size limit; prefer imageUrl to present the chart." },
          "imageUrl": { "type": "string", "format": "uri", "description": "Stable URL that returns the chart as a binary image (PNG by default). Present it as a markdown image to show the chart without inlining a large payload." }
        }
      },
      "Error": {
        "type": "object",
        "required": ["error"],
        "properties": { "error": { "type": "object", "required": ["code", "message"], "properties": { "code": { "type": "string" }, "message": { "type": "string" } } } }
      }
    },
    "responses": {
      "Artifact": {
        "description": "A canonical artifact or an adapter rendering of the same artifact.",
        "content": {
          "application/json": { "schema": { "$ref": "#/components/schemas/FenkiArtifact" } },
          "text/markdown": { "schema": { "type": "string" } },
          "text/plain": { "schema": { "type": "string" } }
        }
      },
      "Error": { "description": "Request error.", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Error" } } } }
    }
  }
}
