{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://surfingdog.ai/spec/schemas/manifest.json",
  "title": "Discovery manifest (/.well-known/agent-inbox.json)",
  "type": "object",
  "properties": {
    "spec": {
      "type": "string",
      "const": "surfingdog-inbox/0"
    },
    "instance": {
      "type": "string",
      "format": "uri"
    },
    "profile": {
      "type": "object",
      "properties": {
        "name": {
          "type": "string",
          "minLength": 1,
          "maxLength": 200
        },
        "description": {
          "type": "string",
          "maxLength": 500
        },
        "categories": {
          "default": [],
          "description": "Slugs from vocab/categories.json (a label or synonym in any of its languages is read as its slug); anything else is kept as a free tag.",
          "maxItems": 10,
          "type": "array",
          "items": {
            "type": "string",
            "maxLength": 60
          }
        },
        "languages": {
          "default": [],
          "maxItems": 10,
          "type": "array",
          "items": {
            "type": "string",
            "maxLength": 12
          }
        },
        "address": {
          "type": "object",
          "properties": {
            "streetAddress": {
              "type": "string",
              "maxLength": 200
            },
            "addressLocality": {
              "type": "string",
              "maxLength": 100
            },
            "postalCode": {
              "type": "string",
              "maxLength": 20
            },
            "addressCountry": {
              "type": "string",
              "minLength": 2,
              "maxLength": 2
            }
          }
        },
        "geo": {
          "type": "object",
          "properties": {
            "latitude": {
              "type": "number",
              "minimum": -90,
              "maximum": 90
            },
            "longitude": {
              "type": "number",
              "minimum": -180,
              "maximum": 180
            }
          },
          "required": ["latitude", "longitude"]
        },
        "url": {
          "type": "string",
          "format": "uri"
        },
        "contact_email": {
          "type": "string",
          "format": "email",
          "pattern": "^(?:[A-Za-z0-9_'+\\-]+\\.)*[A-Za-z0-9_'+\\-]*[A-Za-z0-9_+-]@(?:[A-Za-z0-9][A-Za-z0-9\\-]*\\.)+[A-Za-z]{2,}$"
        },
        "hours": {
          "type": "object",
          "properties": {
            "timezone": {
              "type": "string",
              "minLength": 1,
              "maxLength": 64,
              "description": "IANA zone, e.g. Europe/Lisbon: every time and date in hours is in it."
            },
            "weekly": {
              "type": "object",
              "properties": {
                "mon": {
                  "maxItems": 6,
                  "type": "array",
                  "items": {
                    "type": "array",
                    "prefixItems": [
                      {
                        "type": "string",
                        "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                      },
                      {
                        "type": "string",
                        "pattern": "^(([01]\\d|2[0-3]):[0-5]\\d|24:00)$"
                      }
                    ],
                    "items": false,
                    "minItems": 2,
                    "maxItems": 2
                  }
                },
                "tue": {
                  "maxItems": 6,
                  "type": "array",
                  "items": {
                    "type": "array",
                    "prefixItems": [
                      {
                        "type": "string",
                        "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                      },
                      {
                        "type": "string",
                        "pattern": "^(([01]\\d|2[0-3]):[0-5]\\d|24:00)$"
                      }
                    ],
                    "items": false,
                    "minItems": 2,
                    "maxItems": 2
                  }
                },
                "wed": {
                  "maxItems": 6,
                  "type": "array",
                  "items": {
                    "type": "array",
                    "prefixItems": [
                      {
                        "type": "string",
                        "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                      },
                      {
                        "type": "string",
                        "pattern": "^(([01]\\d|2[0-3]):[0-5]\\d|24:00)$"
                      }
                    ],
                    "items": false,
                    "minItems": 2,
                    "maxItems": 2
                  }
                },
                "thu": {
                  "maxItems": 6,
                  "type": "array",
                  "items": {
                    "type": "array",
                    "prefixItems": [
                      {
                        "type": "string",
                        "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                      },
                      {
                        "type": "string",
                        "pattern": "^(([01]\\d|2[0-3]):[0-5]\\d|24:00)$"
                      }
                    ],
                    "items": false,
                    "minItems": 2,
                    "maxItems": 2
                  }
                },
                "fri": {
                  "maxItems": 6,
                  "type": "array",
                  "items": {
                    "type": "array",
                    "prefixItems": [
                      {
                        "type": "string",
                        "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                      },
                      {
                        "type": "string",
                        "pattern": "^(([01]\\d|2[0-3]):[0-5]\\d|24:00)$"
                      }
                    ],
                    "items": false,
                    "minItems": 2,
                    "maxItems": 2
                  }
                },
                "sat": {
                  "maxItems": 6,
                  "type": "array",
                  "items": {
                    "type": "array",
                    "prefixItems": [
                      {
                        "type": "string",
                        "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                      },
                      {
                        "type": "string",
                        "pattern": "^(([01]\\d|2[0-3]):[0-5]\\d|24:00)$"
                      }
                    ],
                    "items": false,
                    "minItems": 2,
                    "maxItems": 2
                  }
                },
                "sun": {
                  "maxItems": 6,
                  "type": "array",
                  "items": {
                    "type": "array",
                    "prefixItems": [
                      {
                        "type": "string",
                        "pattern": "^([01]\\d|2[0-3]):[0-5]\\d$"
                      },
                      {
                        "type": "string",
                        "pattern": "^(([01]\\d|2[0-3]):[0-5]\\d|24:00)$"
                      }
                    ],
                    "items": false,
                    "minItems": 2,
                    "maxItems": 2
                  }
                }
              }
            },
            "closures": {
              "default": [],
              "maxItems": 100,
              "type": "array",
              "items": {
                "type": "object",
                "properties": {
                  "from": {
                    "type": "string",
                    "format": "date",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
                  },
                  "to": {
                    "type": "string",
                    "format": "date",
                    "pattern": "^(?:(?:\\d\\d[2468][048]|\\d\\d[13579][26]|\\d\\d0[48]|[02468][048]00|[13579][26]00)-02-29|\\d{4}-(?:(?:0[13578]|1[02])-(?:0[1-9]|[12]\\d|3[01])|(?:0[469]|11)-(?:0[1-9]|[12]\\d|30)|(?:02)-(?:0[1-9]|1\\d|2[0-8])))$"
                  }
                },
                "required": ["from", "to"]
              }
            }
          },
          "required": ["timezone", "weekly"]
        },
        "services": {
          "maxItems": 30,
          "type": "array",
          "items": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string",
                "minLength": 1,
                "maxLength": 80
              },
              "type": {
                "type": "string",
                "enum": ["booking", "order", "quote_request"]
              }
            },
            "required": ["name", "type"]
          }
        },
        "place_category": {
          "description": "Overture Place Categories ids (GET /v1/categories?group=…): what the business is, most specific first.",
          "type": "object",
          "properties": {
            "primary": {
              "type": "string",
              "maxLength": 80
            },
            "alternates": {
              "maxItems": 2,
              "type": "array",
              "items": {
                "type": "string",
                "maxLength": 80
              }
            }
          },
          "required": ["primary"]
        },
        "attributes": {
          "description": "Keys of a network's GET /v1/attributes: true, or one of the key's values.",
          "type": "object",
          "propertyNames": {
            "type": "string",
            "maxLength": 60
          },
          "additionalProperties": {
            "anyOf": [
              {
                "type": "boolean"
              },
              {
                "type": "string",
                "maxLength": 60
              }
            ]
          }
        },
        "price_band": {
          "description": "1 (cheapest) to 4.",
          "type": "integer",
          "minimum": 1,
          "maximum": 4
        },
        "currencies": {
          "description": "ISO 4217.",
          "maxItems": 5,
          "type": "array",
          "items": {
            "type": "string",
            "pattern": "^[A-Z]{3}$"
          }
        }
      },
      "required": ["name"]
    },
    "item_types": {
      "type": "array",
      "items": {
        "type": "string",
        "enum": ["message", "quote_request", "booking", "order", "refund"]
      }
    },
    "protocols": {
      "type": "object",
      "propertyNames": {
        "type": "string"
      },
      "additionalProperties": {
        "type": "string",
        "format": "uri"
      }
    },
    "agent_policy": {
      "type": "object",
      "properties": {
        "tiers": {
          "minItems": 1,
          "type": "array",
          "items": {
            "type": "string",
            "enum": ["anonymous", "signed_agent", "verified_principal", "reputed_principal"]
          }
        },
        "signatures": {
          "maxItems": 8,
          "type": "array",
          "items": {
            "type": "string",
            "maxLength": 40
          }
        },
        "passes": {
          "type": "boolean"
        },
        "networks": {
          "maxItems": 8,
          "type": "array",
          "items": {
            "type": "string",
            "format": "uri"
          }
        },
        "guide": {
          "type": "string",
          "format": "uri"
        }
      },
      "required": ["tiers"]
    },
    "receipt_keys": {
      "type": "object",
      "properties": {
        "keys": {
          "type": "array",
          "items": {
            "type": "object",
            "propertyNames": {
              "type": "string"
            },
            "additionalProperties": {}
          }
        }
      },
      "required": ["keys"]
    },
    "review_services": {
      "type": "array",
      "items": {
        "type": "string",
        "format": "uri"
      }
    },
    "directory": {
      "type": "object",
      "properties": {
        "listed": {
          "type": "boolean"
        }
      },
      "required": ["listed"]
    },
    "claims": {
      "type": "object",
      "propertyNames": {
        "type": "string",
        "maxLength": 253
      },
      "additionalProperties": {
        "type": "string",
        "maxLength": 200
      }
    },
    "doors_elsewhere": {
      "maxItems": 5,
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "item_type": {
            "type": "string",
            "enum": ["message", "quote_request", "booking", "order", "refund"]
          },
          "url": {
            "type": "string",
            "maxLength": 2048,
            "format": "uri",
            "description": "Where to go for it: an https page on a named host, with no user or password in it."
          }
        },
        "required": ["item_type", "url"]
      }
    }
  },
  "required": ["spec", "instance", "item_types", "protocols", "agent_policy", "receipt_keys", "review_services"]
}
