{
  "openapi": "3.1.0",
  "info": {
    "title": "ExhibitSet API",
    "version": "0.2.0",
    "description": "Accounts, billing, entitlements and matter metadata. This API never receives documents."
  },
  "components": {
    "schemas": {},
    "parameters": {}
  },
  "paths": {
    "/health": {
      "get": {
        "responses": {
          "200": {
            "description": "Alive",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    }
                  },
                  "required": [
                    "ok"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/.well-known/entitlement-key": {
      "get": {
        "responses": {
          "200": {
            "description": "Public key for entitlement tokens",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "keys": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "additionalProperties": {
                          "nullable": true
                        }
                      }
                    }
                  },
                  "required": [
                    "keys"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/auth/code": {
      "post": {
        "requestBody": {
          "description": "The address, and the sign-in challenge token when the service is configured with one",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 320
                  },
                  "turnstileToken": {
                    "type": "string",
                    "maxLength": 4096
                  }
                },
                "required": [
                  "email"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Sent if the address is valid",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    }
                  },
                  "required": [
                    "ok"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "The challenge was not solved",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Too many requests",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/auth/code/verify": {
      "post": {
        "requestBody": {
          "description": "The code from the e-mail",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 320
                  },
                  "code": {
                    "type": "string",
                    "pattern": "^\\d{6}$"
                  }
                },
                "required": [
                  "email",
                  "code"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Signed in; the session cookie is set",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    },
                    "email": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "ok",
                    "email"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Wrong or expired code",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "429": {
            "description": "Too many attempts",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/auth/logout": {
      "post": {
        "responses": {
          "200": {
            "description": "Signed out",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "enum": [
                        true
                      ]
                    }
                  },
                  "required": [
                    "ok"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/me": {
      "get": {
        "responses": {
          "200": {
            "description": "The signed-in user",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "email": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "email"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Not signed in",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/me/entitlement": {
      "get": {
        "responses": {
          "200": {
            "description": "Limits now, plus a signed token for seven days offline",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "limits": {
                      "type": "object",
                      "properties": {
                        "plan": {
                          "type": "string",
                          "enum": [
                            "free",
                            "pro",
                            "firm",
                            "matter-pass"
                          ]
                        },
                        "seats": {
                          "type": "number"
                        },
                        "stampJobsPerMonth": {
                          "type": "number",
                          "nullable": true
                        },
                        "stampJobsUsed": {
                          "type": "number"
                        },
                        "validUntil": {
                          "type": "string",
                          "nullable": true
                        },
                        "redactionUnlimited": {
                          "type": "boolean",
                          "enum": [
                            true
                          ]
                        }
                      },
                      "required": [
                        "plan",
                        "seats",
                        "stampJobsPerMonth",
                        "stampJobsUsed",
                        "validUntil",
                        "redactionUnlimited"
                      ]
                    },
                    "token": {
                      "type": "string"
                    },
                    "plans": {
                      "type": "object",
                      "additionalProperties": {
                        "type": "object",
                        "properties": {
                          "name": {
                            "type": "string"
                          },
                          "description": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "name",
                          "description"
                        ]
                      }
                    }
                  },
                  "required": [
                    "limits",
                    "token",
                    "plans"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/me/usage/stamp-job": {
      "post": {
        "responses": {
          "200": {
            "description": "Counted",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "limits": {
                      "type": "object",
                      "properties": {
                        "plan": {
                          "type": "string",
                          "enum": [
                            "free",
                            "pro",
                            "firm",
                            "matter-pass"
                          ]
                        },
                        "seats": {
                          "type": "number"
                        },
                        "stampJobsPerMonth": {
                          "type": "number",
                          "nullable": true
                        },
                        "stampJobsUsed": {
                          "type": "number"
                        },
                        "validUntil": {
                          "type": "string",
                          "nullable": true
                        },
                        "redactionUnlimited": {
                          "type": "boolean",
                          "enum": [
                            true
                          ]
                        }
                      },
                      "required": [
                        "plan",
                        "seats",
                        "stampJobsPerMonth",
                        "stampJobsUsed",
                        "validUntil",
                        "redactionUnlimited"
                      ]
                    }
                  },
                  "required": [
                    "limits"
                  ]
                }
              }
            }
          },
          "402": {
            "description": "Over the plan limit",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    },
                    "limits": {
                      "type": "object",
                      "properties": {
                        "plan": {
                          "type": "string",
                          "enum": [
                            "free",
                            "pro",
                            "firm",
                            "matter-pass"
                          ]
                        },
                        "seats": {
                          "type": "number"
                        },
                        "stampJobsPerMonth": {
                          "type": "number",
                          "nullable": true
                        },
                        "stampJobsUsed": {
                          "type": "number"
                        },
                        "validUntil": {
                          "type": "string",
                          "nullable": true
                        },
                        "redactionUnlimited": {
                          "type": "boolean",
                          "enum": [
                            true
                          ]
                        }
                      },
                      "required": [
                        "plan",
                        "seats",
                        "stampJobsPerMonth",
                        "stampJobsUsed",
                        "validUntil",
                        "redactionUnlimited"
                      ]
                    }
                  },
                  "required": [
                    "error",
                    "limits"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/billing/checkout": {
      "post": {
        "requestBody": {
          "description": "What to buy",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "product": {
                    "type": "string",
                    "enum": [
                      "pro-monthly",
                      "pro-annual",
                      "firm-monthly",
                      "firm-annual",
                      "matter-pass"
                    ]
                  }
                },
                "required": [
                  "product"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Stripe Checkout URL",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "url": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "url"
                  ]
                }
              }
            }
          },
          "503": {
            "description": "Billing not configured",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/billing/portal": {
      "post": {
        "responses": {
          "200": {
            "description": "Customer Portal URL",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "url": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "url"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "No billing account yet",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "503": {
            "description": "Billing not configured",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/matters": {
      "get": {
        "responses": {
          "200": {
            "description": "Your matters",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "matters": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "name": {
                            "type": "string"
                          },
                          "clientRef": {
                            "type": "string"
                          },
                          "batesPrefix": {
                            "type": "string"
                          },
                          "batesDigits": {
                            "type": "number"
                          },
                          "nextNumber": {
                            "type": "number"
                          },
                          "lastNumber": {
                            "type": "number",
                            "nullable": true
                          },
                          "preflightProfile": {
                            "type": "string"
                          },
                          "role": {
                            "type": "string",
                            "enum": [
                              "owner",
                              "member"
                            ]
                          },
                          "archived": {
                            "type": "boolean"
                          }
                        },
                        "required": [
                          "id",
                          "name",
                          "clientRef",
                          "batesPrefix",
                          "batesDigits",
                          "nextNumber",
                          "lastNumber",
                          "preflightProfile",
                          "role",
                          "archived"
                        ]
                      }
                    }
                  },
                  "required": [
                    "matters"
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "requestBody": {
          "description": "New matter",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "clientRef": {
                    "type": "string",
                    "maxLength": 100
                  },
                  "batesPrefix": {
                    "type": "string",
                    "maxLength": 40
                  },
                  "batesDigits": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 12
                  },
                  "startNumber": {
                    "type": "integer",
                    "minimum": 1
                  },
                  "preflightProfile": {
                    "type": "string",
                    "maxLength": 40
                  }
                },
                "required": [
                  "name"
                ]
              }
            }
          }
        },
        "responses": {
          "201": {
            "description": "Created",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "clientRef": {
                      "type": "string"
                    },
                    "batesPrefix": {
                      "type": "string"
                    },
                    "batesDigits": {
                      "type": "number"
                    },
                    "nextNumber": {
                      "type": "number"
                    },
                    "lastNumber": {
                      "type": "number",
                      "nullable": true
                    },
                    "preflightProfile": {
                      "type": "string"
                    },
                    "role": {
                      "type": "string",
                      "enum": [
                        "owner",
                        "member"
                      ]
                    },
                    "archived": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "id",
                    "name",
                    "clientRef",
                    "batesPrefix",
                    "batesDigits",
                    "nextNumber",
                    "lastNumber",
                    "preflightProfile",
                    "role",
                    "archived"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/matters/{id}": {
      "get": {
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "The matter",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "clientRef": {
                      "type": "string"
                    },
                    "batesPrefix": {
                      "type": "string"
                    },
                    "batesDigits": {
                      "type": "number"
                    },
                    "nextNumber": {
                      "type": "number"
                    },
                    "lastNumber": {
                      "type": "number",
                      "nullable": true
                    },
                    "preflightProfile": {
                      "type": "string"
                    },
                    "role": {
                      "type": "string",
                      "enum": [
                        "owner",
                        "member"
                      ]
                    },
                    "archived": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "id",
                    "name",
                    "clientRef",
                    "batesPrefix",
                    "batesDigits",
                    "nextNumber",
                    "lastNumber",
                    "preflightProfile",
                    "role",
                    "archived"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        }
      },
      "patch": {
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "description": "Changes",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "name": {
                    "type": "string",
                    "minLength": 1,
                    "maxLength": 200
                  },
                  "clientRef": {
                    "type": "string",
                    "maxLength": 100
                  },
                  "batesPrefix": {
                    "type": "string",
                    "maxLength": 40
                  },
                  "batesDigits": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 12
                  },
                  "startNumber": {
                    "type": "integer",
                    "minimum": 1
                  },
                  "preflightProfile": {
                    "type": "string",
                    "maxLength": 40
                  },
                  "archived": {
                    "type": "boolean"
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Updated",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "clientRef": {
                      "type": "string"
                    },
                    "batesPrefix": {
                      "type": "string"
                    },
                    "batesDigits": {
                      "type": "number"
                    },
                    "nextNumber": {
                      "type": "number"
                    },
                    "lastNumber": {
                      "type": "number",
                      "nullable": true
                    },
                    "preflightProfile": {
                      "type": "string"
                    },
                    "role": {
                      "type": "string",
                      "enum": [
                        "owner",
                        "member"
                      ]
                    },
                    "archived": {
                      "type": "boolean"
                    }
                  },
                  "required": [
                    "id",
                    "name",
                    "clientRef",
                    "batesPrefix",
                    "batesDigits",
                    "nextNumber",
                    "lastNumber",
                    "preflightProfile",
                    "role",
                    "archived"
                  ]
                }
              }
            }
          },
          "403": {
            "description": "Owner only",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/matters/{id}/bates/reserve": {
      "post": {
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "description": "How many numbers",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "count": {
                    "type": "integer",
                    "minimum": 1,
                    "maximum": 1000000
                  },
                  "note": {
                    "type": "string",
                    "maxLength": 200
                  }
                },
                "required": [
                  "count"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "The reserved range [start, end)",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "matterId": {
                      "type": "string"
                    },
                    "start": {
                      "type": "number"
                    },
                    "end": {
                      "type": "number"
                    },
                    "count": {
                      "type": "number"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "reserved",
                        "confirmed",
                        "released"
                      ]
                    },
                    "note": {
                      "type": "string"
                    },
                    "createdAt": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "matterId",
                    "start",
                    "end",
                    "count",
                    "status",
                    "note",
                    "createdAt"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Not found or archived",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/matters/{id}/bates/reservations/{rid}/confirm": {
      "post": {
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "rid",
            "in": "path"
          }
        ],
        "requestBody": {
          "description": "Numbers actually used",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "used": {
                    "type": "integer",
                    "minimum": 0
                  }
                }
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Confirmed",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "matterId": {
                      "type": "string"
                    },
                    "start": {
                      "type": "number"
                    },
                    "end": {
                      "type": "number"
                    },
                    "count": {
                      "type": "number"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "reserved",
                        "confirmed",
                        "released"
                      ]
                    },
                    "note": {
                      "type": "string"
                    },
                    "createdAt": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "matterId",
                    "start",
                    "end",
                    "count",
                    "status",
                    "note",
                    "createdAt"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/matters/{id}/bates/reservations/{rid}/release": {
      "post": {
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "rid",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Released",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "id": {
                      "type": "string"
                    },
                    "matterId": {
                      "type": "string"
                    },
                    "start": {
                      "type": "number"
                    },
                    "end": {
                      "type": "number"
                    },
                    "count": {
                      "type": "number"
                    },
                    "status": {
                      "type": "string",
                      "enum": [
                        "reserved",
                        "confirmed",
                        "released"
                      ]
                    },
                    "note": {
                      "type": "string"
                    },
                    "createdAt": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "id",
                    "matterId",
                    "start",
                    "end",
                    "count",
                    "status",
                    "note",
                    "createdAt"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/matters/{id}/bates/reservations": {
      "get": {
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Ranges, newest first",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "reservations": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "id": {
                            "type": "string"
                          },
                          "matterId": {
                            "type": "string"
                          },
                          "start": {
                            "type": "number"
                          },
                          "end": {
                            "type": "number"
                          },
                          "count": {
                            "type": "number"
                          },
                          "status": {
                            "type": "string",
                            "enum": [
                              "reserved",
                              "confirmed",
                              "released"
                            ]
                          },
                          "note": {
                            "type": "string"
                          },
                          "createdAt": {
                            "type": "string"
                          }
                        },
                        "required": [
                          "id",
                          "matterId",
                          "start",
                          "end",
                          "count",
                          "status",
                          "note",
                          "createdAt"
                        ]
                      }
                    }
                  },
                  "required": [
                    "reservations"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/matters/{id}/members": {
      "get": {
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Members",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "members": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "userId": {
                            "type": "string"
                          },
                          "email": {
                            "type": "string"
                          },
                          "role": {
                            "type": "string",
                            "enum": [
                              "owner",
                              "member"
                            ]
                          }
                        },
                        "required": [
                          "userId",
                          "email",
                          "role"
                        ]
                      }
                    }
                  },
                  "required": [
                    "members"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        }
      },
      "post": {
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "id",
            "in": "path"
          }
        ],
        "requestBody": {
          "description": "Who to add",
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "email": {
                    "type": "string",
                    "minLength": 3,
                    "maxLength": 320
                  }
                },
                "required": [
                  "email"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Members",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "members": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "userId": {
                            "type": "string"
                          },
                          "email": {
                            "type": "string"
                          },
                          "role": {
                            "type": "string",
                            "enum": [
                              "owner",
                              "member"
                            ]
                          }
                        },
                        "required": [
                          "userId",
                          "email",
                          "role"
                        ]
                      }
                    }
                  },
                  "required": [
                    "members"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Cannot add",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        }
      }
    },
    "/matters/{id}/members/{userId}": {
      "delete": {
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "id",
            "in": "path"
          },
          {
            "schema": {
              "type": "string"
            },
            "required": true,
            "name": "userId",
            "in": "path"
          }
        ],
        "responses": {
          "200": {
            "description": "Members",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "members": {
                      "type": "array",
                      "items": {
                        "type": "object",
                        "properties": {
                          "userId": {
                            "type": "string"
                          },
                          "email": {
                            "type": "string"
                          },
                          "role": {
                            "type": "string",
                            "enum": [
                              "owner",
                              "member"
                            ]
                          }
                        },
                        "required": [
                          "userId",
                          "email",
                          "role"
                        ]
                      }
                    }
                  },
                  "required": [
                    "members"
                  ]
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "error": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "error"
                  ]
                }
              }
            }
          }
        }
      }
    }
  },
  "servers": [
    {
      "url": "https://api.exhibitset.com",
      "description": "Production"
    }
  ]
}
