{
  "components": {
    "schemas": {
      "EntitlementOut": {
        "properties": {
          "active": {
            "title": "Active",
            "type": "boolean"
          },
          "until": {
            "title": "Until",
            "type": "integer"
          }
        },
        "required": [
          "active",
          "until"
        ],
        "title": "EntitlementOut",
        "type": "object"
      },
      "HTTPValidationError": {
        "properties": {
          "detail": {
            "items": {
              "$ref": "#/components/schemas/ValidationError"
            },
            "title": "Detail",
            "type": "array"
          }
        },
        "title": "HTTPValidationError",
        "type": "object"
      },
      "HandshakeResponse": {
        "properties": {
          "config_hash": {
            "title": "Config Hash",
            "type": "string"
          },
          "entitlement": {
            "$ref": "#/components/schemas/EntitlementOut"
          },
          "features": {
            "additionalProperties": {
              "anyOf": [
                {
                  "type": "boolean"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "title": "Features",
            "type": "object"
          },
          "latest_resource_version": {
            "title": "Latest Resource Version",
            "type": "string"
          },
          "server_id": {
            "format": "uuid",
            "title": "Server Id",
            "type": "string"
          },
          "server_time": {
            "title": "Server Time",
            "type": "integer"
          },
          "token": {
            "title": "Token",
            "type": "string"
          }
        },
        "required": [
          "server_id",
          "token",
          "config_hash",
          "features",
          "latest_resource_version",
          "server_time",
          "entitlement"
        ],
        "title": "HandshakeResponse",
        "type": "object"
      },
      "PublicTermination": {
        "additionalProperties": false,
        "properties": {
          "contact": {
            "maxLength": 320,
            "minLength": 1,
            "title": "Contact",
            "type": "string"
          },
          "kind": {
            "default": "termination",
            "enum": [
              "termination",
              "withdrawal"
            ],
            "title": "Kind",
            "type": "string"
          },
          "reference": {
            "maxLength": 128,
            "minLength": 1,
            "title": "Reference",
            "type": "string"
          }
        },
        "required": [
          "reference",
          "contact"
        ],
        "title": "PublicTermination",
        "type": "object"
      },
      "ValidationError": {
        "properties": {
          "ctx": {
            "title": "Context",
            "type": "object"
          },
          "input": {
            "title": "Input"
          },
          "loc": {
            "items": {
              "anyOf": [
                {
                  "type": "string"
                },
                {
                  "type": "integer"
                }
              ]
            },
            "title": "Location",
            "type": "array"
          },
          "msg": {
            "title": "Message",
            "type": "string"
          },
          "type": {
            "title": "Error Type",
            "type": "string"
          }
        },
        "required": [
          "loc",
          "msg",
          "type"
        ],
        "title": "ValidationError",
        "type": "object"
      }
    }
  },
  "info": {
    "title": "Bastrel API",
    "version": "0.1.0"
  },
  "openapi": "3.1.0",
  "paths": {
    "/v1/bans": {
      "post": {
        "description": "Record a ban of the resource with the detections it rests on. Idempotent on `ban_id`.",
        "operationId": "create_ban_v1_bans_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$defs": {
                  "BanItem": {
                    "additionalProperties": false,
                    "properties": {
                      "ban_id": {
                        "pattern": "^BAS-[0-9A-HJKMNP-TV-Z]{8}$",
                        "title": "Ban Id",
                        "type": "string"
                      },
                      "code": {
                        "pattern": "^BAS-[A-Z]{2,5}-[0-9]{3}$",
                        "title": "Code",
                        "type": "string"
                      },
                      "created_at": {
                        "format": "date-time",
                        "title": "Created At",
                        "type": "string"
                      },
                      "detection_ids": {
                        "items": {
                          "pattern": "^[A-Za-z0-9._:-]{1,128}$",
                          "type": "string"
                        },
                        "maxItems": 32,
                        "minItems": 1,
                        "title": "Detection Ids",
                        "type": "array"
                      },
                      "expires_at": {
                        "anyOf": [
                          {
                            "format": "date-time",
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "title": "Expires At"
                      },
                      "identifiers": {
                        "items": {
                          "$ref": "#/$defs/Identifier"
                        },
                        "maxItems": 64,
                        "minItems": 1,
                        "title": "Identifiers",
                        "type": "array"
                      },
                      "issued_by": {
                        "pattern": "^(console|system|staff:[0-9a-f]{64})$",
                        "title": "Issued By",
                        "type": "string"
                      },
                      "reason": {
                        "maxLength": 255,
                        "minLength": 1,
                        "title": "Reason",
                        "type": "string"
                      },
                      "revoked_at": {
                        "anyOf": [
                          {
                            "format": "date-time",
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "title": "Revoked At"
                      },
                      "revoked_by": {
                        "anyOf": [
                          {
                            "pattern": "^(console|system|staff:[0-9a-f]{64})$",
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "title": "Revoked By"
                      },
                      "revoked_reason": {
                        "anyOf": [
                          {
                            "maxLength": 255,
                            "minLength": 1,
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "title": "Revoked Reason"
                      },
                      "scope": {
                        "const": "local",
                        "default": "local",
                        "title": "Scope",
                        "type": "string"
                      },
                      "status": {
                        "enum": [
                          "active",
                          "appealed",
                          "revoked"
                        ],
                        "title": "Status",
                        "type": "string"
                      }
                    },
                    "required": [
                      "ban_id",
                      "status",
                      "code",
                      "reason",
                      "issued_by",
                      "created_at",
                      "identifiers",
                      "detection_ids"
                    ],
                    "title": "BanItem",
                    "type": "object"
                  },
                  "Identifier": {
                    "additionalProperties": false,
                    "properties": {
                      "kind": {
                        "enum": [
                          "license_ref",
                          "token_ref"
                        ],
                        "title": "Kind",
                        "type": "string"
                      },
                      "network_ref": {
                        "anyOf": [
                          {
                            "pattern": "^[0-9a-f]{64}$",
                            "type": "string"
                          },
                          {
                            "type": "null"
                          }
                        ],
                        "title": "Network Ref"
                      },
                      "ref": {
                        "pattern": "^[0-9a-f]{64}$",
                        "title": "Ref",
                        "type": "string"
                      }
                    },
                    "required": [
                      "kind",
                      "ref"
                    ],
                    "title": "Identifier",
                    "type": "object"
                  }
                },
                "additionalProperties": false,
                "properties": {
                  "ban": {
                    "$ref": "#/$defs/BanItem"
                  },
                  "kind": {
                    "const": "bans",
                    "title": "Kind",
                    "type": "string"
                  },
                  "resource_version": {
                    "maxLength": 64,
                    "minLength": 1,
                    "title": "Resource Version",
                    "type": "string"
                  },
                  "server_uuid": {
                    "format": "uuid",
                    "title": "Server Uuid",
                    "type": "string"
                  }
                },
                "required": [
                  "kind",
                  "server_uuid",
                  "resource_version",
                  "ban"
                ],
                "title": "BanEnvelope",
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Create Ban",
        "tags": [
          "resource"
        ]
      }
    },
    "/v1/bans/{ban_id}": {
      "patch": {
        "description": "Put a ban under appeal or lift it. A lifting is final; repeating it changes nothing. Only the\nserver that created a ban changes it (an id is drawn locally: two servers of an account may\nhold the same one).",
        "operationId": "change_ban_v1_bans__ban_id__patch",
        "parameters": [
          {
            "in": "path",
            "name": "ban_id",
            "required": true,
            "schema": {
              "pattern": "^BAS-[0-9A-HJKMNP-TV-Z]{8}$",
              "title": "Ban Id",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "kind": {
                    "const": "bans",
                    "title": "Kind",
                    "type": "string"
                  },
                  "resource_version": {
                    "maxLength": 64,
                    "minLength": 1,
                    "title": "Resource Version",
                    "type": "string"
                  },
                  "revoked_at": {
                    "anyOf": [
                      {
                        "format": "date-time",
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "title": "Revoked At"
                  },
                  "revoked_by": {
                    "anyOf": [
                      {
                        "pattern": "^(console|system|staff:[0-9a-f]{64})$",
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "title": "Revoked By"
                  },
                  "revoked_reason": {
                    "anyOf": [
                      {
                        "maxLength": 255,
                        "minLength": 1,
                        "type": "string"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "title": "Revoked Reason"
                  },
                  "server_uuid": {
                    "format": "uuid",
                    "title": "Server Uuid",
                    "type": "string"
                  },
                  "status": {
                    "enum": [
                      "appealed",
                      "revoked"
                    ],
                    "title": "Status",
                    "type": "string"
                  }
                },
                "required": [
                  "kind",
                  "server_uuid",
                  "resource_version",
                  "status"
                ],
                "title": "BanChange",
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Change Ban",
        "tags": [
          "resource"
        ]
      }
    },
    "/v1/bans:changes": {
      "get": {
        "description": "The bans of the tenant (all its servers) that changed after the cursor `since`.\n\nThe answer is signed (response signature, bound to the nonce): a forged answer must not be able\nto lift the bans of a server. It is served without an active subscription: a lifting decided\nbefore the end of the subscription must still reach the server.",
        "operationId": "bans_changes_v1_bans_changes_get",
        "parameters": [
          {
            "in": "query",
            "name": "since",
            "required": false,
            "schema": {
              "default": 0,
              "maximum": 4611686018427387904,
              "minimum": 0,
              "title": "Since",
              "type": "integer"
            }
          },
          {
            "in": "query",
            "name": "limit",
            "required": false,
            "schema": {
              "default": 500,
              "maximum": 500,
              "minimum": 1,
              "title": "Limit",
              "type": "integer"
            }
          }
        ],
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Bans Changes",
        "tags": [
          "resource"
        ]
      }
    },
    "/v1/bans:lookup": {
      "post": {
        "description": "Whether the references match a ban in force of another tenant that opted in. A signal.",
        "operationId": "lookup_bans_v1_bans_lookup_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "refs": {
                    "items": {
                      "pattern": "^[0-9a-f]{64}$",
                      "type": "string"
                    },
                    "maxItems": 8,
                    "minItems": 1,
                    "title": "Refs",
                    "type": "array"
                  },
                  "resource_version": {
                    "maxLength": 64,
                    "minLength": 1,
                    "title": "Resource Version",
                    "type": "string"
                  },
                  "server_uuid": {
                    "format": "uuid",
                    "title": "Server Uuid",
                    "type": "string"
                  }
                },
                "required": [
                  "server_uuid",
                  "resource_version",
                  "refs"
                ],
                "title": "LookupBody",
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Lookup Bans",
        "tags": [
          "resource"
        ]
      }
    },
    "/v1/config": {
      "get": {
        "description": "The config of the server, signed; 304 when the caller already holds it.\n\nThe config is served only with an active subscription whose plan has `panel_config`; the\nanswer always tells the entitlement, so that the resource learns it between two handshakes.",
        "operationId": "get_config_v1_config_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Get Config",
        "tags": [
          "resource"
        ]
      }
    },
    "/v1/detections:batch": {
      "post": {
        "description": "Ingest up to 500 detections or economy transactions of the authenticated server.",
        "operationId": "detections_batch_v1_detections_batch_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "items": {
                    "items": {},
                    "maxItems": 500,
                    "minItems": 1,
                    "title": "Items",
                    "type": "array"
                  },
                  "kind": {
                    "enum": [
                      "detections",
                      "transactions"
                    ],
                    "title": "Kind",
                    "type": "string"
                  },
                  "resource_version": {
                    "maxLength": 64,
                    "minLength": 1,
                    "title": "Resource Version",
                    "type": "string"
                  },
                  "server_uuid": {
                    "format": "uuid",
                    "title": "Server Uuid",
                    "type": "string"
                  }
                },
                "required": [
                  "kind",
                  "server_uuid",
                  "resource_version",
                  "items"
                ],
                "title": "BatchEnvelope",
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Detections Batch",
        "tags": [
          "resource"
        ]
      }
    },
    "/v1/health": {
      "get": {
        "description": "Liveness probe. Touches no dependency.",
        "operationId": "health_v1_health_get",
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "additionalProperties": {
                    "type": "string"
                  },
                  "title": "Response Health V1 Health Get",
                  "type": "object"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Health",
        "tags": [
          "public"
        ]
      }
    },
    "/v1/public/terminations": {
      "post": {
        "description": "Ask to end a subscription without signing in. Rate limited; the answer is the same whether or not the reference exists.",
        "operationId": "terminate_v1_public_terminations_post",
        "parameters": [
          {
            "in": "query",
            "name": "lang",
            "required": false,
            "schema": {
              "default": "en",
              "title": "Lang",
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/PublicTermination"
              }
            }
          },
          "required": true
        },
        "responses": {
          "202": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          },
          "422": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HTTPValidationError"
                }
              }
            },
            "description": "Validation Error"
          }
        },
        "summary": "Terminate",
        "tags": [
          "public"
        ]
      }
    },
    "/v1/servers/handshake": {
      "post": {
        "description": "Validate the licence, register the server and return a signed licence token.",
        "operationId": "handshake_v1_servers_handshake_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "additionalProperties": false,
                "properties": {
                  "framework": {
                    "maxLength": 32,
                    "minLength": 1,
                    "title": "Framework",
                    "type": "string"
                  },
                  "fx_artifact": {
                    "maxLength": 64,
                    "minLength": 1,
                    "title": "Fx Artifact",
                    "type": "string"
                  },
                  "modules": {
                    "items": {
                      "maxLength": 64,
                      "minLength": 1,
                      "type": "string"
                    },
                    "maxItems": 64,
                    "title": "Modules",
                    "type": "array"
                  },
                  "resmon": {
                    "anyOf": [
                      {
                        "maximum": 1000.0,
                        "minimum": 0.0,
                        "type": "number"
                      },
                      {
                        "type": "null"
                      }
                    ],
                    "title": "Resmon"
                  },
                  "resource_version": {
                    "maxLength": 64,
                    "minLength": 1,
                    "title": "Resource Version",
                    "type": "string"
                  },
                  "server_kind": {
                    "enum": [
                      "production",
                      "dev"
                    ],
                    "title": "Server Kind",
                    "type": "string"
                  },
                  "server_uuid": {
                    "format": "uuid",
                    "title": "Server Uuid",
                    "type": "string"
                  }
                },
                "required": [
                  "server_uuid",
                  "resource_version",
                  "fx_artifact",
                  "server_kind",
                  "framework",
                  "modules"
                ],
                "title": "HandshakeRequest",
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/HandshakeResponse"
                }
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Handshake",
        "tags": [
          "resource"
        ]
      }
    },
    "/v1/webhooks/tebex": {
      "post": {
        "description": "Receive a payment-platform (Tebex) webhook.",
        "operationId": "tebex_webhook_v1_webhooks_tebex_post",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "description": "`{ id, type, date, subject }`; the subject is read by the state machine, leniently.",
                "properties": {
                  "date": {
                    "title": "Date"
                  },
                  "id": {
                    "maxLength": 128,
                    "minLength": 1,
                    "title": "Id",
                    "type": "string"
                  },
                  "subject": {
                    "title": "Subject"
                  },
                  "type": {
                    "maxLength": 64,
                    "minLength": 1,
                    "title": "Type",
                    "type": "string"
                  }
                },
                "required": [
                  "id",
                  "type"
                ],
                "title": "TebexEnvelope",
                "type": "object"
              }
            }
          },
          "required": true
        },
        "responses": {
          "200": {
            "content": {
              "application/json": {
                "schema": {}
              }
            },
            "description": "Successful Response"
          }
        },
        "summary": "Tebex Webhook",
        "tags": [
          "webhook"
        ]
      }
    }
  }
}
