{
  "openapi": "3.1.0",
  "info": {
    "title": "InnerCartography public data",
    "version": "1.0.0",
    "summary": "Read-only data about InnerCartography's engagements and hyperblogs.",
    "description": "Static, read-only JSON. There is deliberately no endpoint that accepts requests: InnerCartography goes into real places and needs to know who is asking and where, so capture and project requests are sent by people at https://innercartography.one/#book. Agents may help a person draft a request but must not send it. See https://innercartography.one/agents.md.",
    "contact": {
      "name": "InnerCartography",
      "email": "michael444@innercartography.one",
      "url": "https://innercartography.one/developers/"
    }
  },
  "servers": [
    {
      "url": "https://innercartography.one"
    }
  ],
  "paths": {
    "/api/services.json": {
      "get": {
        "operationId": "getServices",
        "summary": "Engagements, starting prices, scope and intake policy",
        "description": "Generated from the live pricing section. $500 is the starting price for one small space, not a per-unit or per-property rate.",
        "responses": {
          "200": {
            "description": "Services",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Services"
                }
              }
            }
          },
          "404": {
            "description": "Not found. Returned as JSON for any unknown /api/ path.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Unexpected error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/blog-index.json": {
      "get": {
        "operationId": "listHyperblogs",
        "summary": "Every hyperblog (essays and prototypes)",
        "description": "Also available at /api/hyperblogs.",
        "responses": {
          "200": {
            "description": "Hyperblogs",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "items": {
                    "$ref": "#/components/schemas/Hyperblog"
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not found. Returned as JSON for any unknown /api/ path.",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "default": {
            "description": "Unexpected error",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "schemas": {
      "Services": {
        "type": "object",
        "properties": {
          "name": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri"
          },
          "description": {
            "type": "string"
          },
          "area_served": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "contact": {
            "type": "object",
            "properties": {
              "email": {
                "type": "string"
              },
              "request_form": {
                "type": "string",
                "format": "uri"
              }
            }
          },
          "intake_policy": {
            "type": "object",
            "description": "Requests are human-only. required_fields lists what a request must include."
          },
          "pricing_note": {
            "type": "string"
          },
          "price_factors": {
            "type": "array",
            "items": {
              "type": "string"
            }
          },
          "engagements": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/Engagement"
            }
          },
          "layers": {
            "type": "array",
            "items": {
              "type": "object"
            }
          }
        },
        "required": [
          "name",
          "url",
          "intake_policy",
          "engagements"
        ]
      },
      "Engagement": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "family": {
            "type": "string",
            "enum": [
              "capture",
              "systems"
            ]
          },
          "scale": {
            "type": "string"
          },
          "price": {
            "type": "object",
            "properties": {
              "qualifier": {
                "type": "string"
              },
              "display": {
                "type": "string"
              },
              "min_usd": {
                "type": [
                  "integer",
                  "null"
                ],
                "description": "Starting price in USD, or null when scoped"
              },
              "currency": {
                "type": "string"
              }
            },
            "required": [
              "display",
              "min_usd",
              "currency"
            ]
          },
          "description": {
            "type": "string"
          },
          "scope_note": {
            "type": "string"
          },
          "includes": {
            "type": "array",
            "items": {
              "type": "string"
            }
          }
        },
        "required": [
          "id",
          "name",
          "family",
          "price"
        ]
      },
      "Hyperblog": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "date": {
            "type": "string",
            "format": "date"
          },
          "description": {
            "type": "string"
          },
          "thumbnail": {
            "type": "string"
          },
          "url": {
            "type": "string",
            "format": "uri",
            "description": "Present only for hyperblogs hosted elsewhere"
          }
        },
        "required": [
          "slug",
          "title"
        ]
      },
      "Error": {
        "type": "object",
        "required": [
          "error"
        ],
        "properties": {
          "error": {
            "type": "object",
            "required": [
              "status",
              "code",
              "message"
            ],
            "properties": {
              "status": {
                "type": "integer",
                "description": "HTTP status code"
              },
              "code": {
                "type": "string",
                "description": "Machine-readable error code, e.g. not_found"
              },
              "message": {
                "type": "string",
                "description": "What went wrong, in plain language"
              },
              "endpoints": {
                "type": "object",
                "additionalProperties": {
                  "type": "string",
                  "format": "uri"
                },
                "description": "The endpoints that do exist"
              },
              "docs": {
                "type": "string",
                "format": "uri"
              },
              "note": {
                "type": "string"
              }
            }
          }
        }
      }
    }
  }
}
