{
  "openapi": "3.1.0",
  "info": {
    "title": "ASCENT 27 API",
    "version": "1.0.0",
    "description": "Halvora and ASCENT 27 are fictional, and this site is a Zephyr demonstration. The public read endpoints serve the event's published content and live totals, never personal records; the demo key ascent27_public_demo opens them, 60 requests a minute per address. The print-on-demand endpoints need a key made in the admin, 600 requests a minute per key."
  },
  "servers": [
    {
      "url": "https://ascent27.zephyr.events"
    }
  ],
  "tags": [
    {
      "name": "Public read",
      "description": "Content and totals; the demo key works."
    },
    {
      "name": "Print on demand",
      "description": "Badge printers and session scanners; a key made in the admin."
    }
  ],
  "security": [
    {
      "apiKey": []
    }
  ],
  "paths": {
    "/api/public/v1/event": {
      "get": {
        "tags": [
          "Public read"
        ],
        "operationId": "event",
        "summary": "The event: names, dates, venue, the three days and the two passes with their prices.",
        "parameters": [
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "description": "en (the default), es, fr or de: the language of the text.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "event": {
                      "$ref": "#/components/schemas/Event"
                    }
                  },
                  "required": [
                    "ok",
                    "event"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, wrong or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/public/v1/sessions": {
      "get": {
        "tags": [
          "Public read"
        ],
        "operationId": "sessions",
        "summary": "The programme by day and time (or by title), filtered by day, kind and text, a page at a time.",
        "parameters": [
          {
            "name": "day",
            "in": "query",
            "required": false,
            "description": "A date (2027-05-19), a weekday (wednesday) or a day name (the climb).",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "kind",
            "in": "query",
            "required": false,
            "description": "keynote, session, workshop, social, registration or exhibits.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Words to find in the title, description, room and speakers, in English or in the language asked; every word must match.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "time (by day and time, the default) or title.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "dir",
            "in": "query",
            "required": false,
            "description": "asc (the default) or desc.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "How many to return, 1 to 100, default 25.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "How many matches to skip, default 0: 25 for the second page of 25.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "description": "en (the default), es, fr or de: the language of the text.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "total": {
                      "type": "integer"
                    },
                    "offset": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "sessions": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Session"
                      }
                    }
                  },
                  "required": [
                    "ok",
                    "total",
                    "offset",
                    "limit",
                    "count",
                    "sessions"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, wrong or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/public/v1/sessions/{id}": {
      "get": {
        "tags": [
          "Public read"
        ],
        "operationId": "session",
        "summary": "One session with its speakers.",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "The session id from /sessions.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "description": "en (the default), es, fr or de: the language of the text.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "session": {
                      "$ref": "#/components/schemas/Session"
                    }
                  },
                  "required": [
                    "ok",
                    "session"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, wrong or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/public/v1/speakers": {
      "get": {
        "tags": [
          "Public read"
        ],
        "operationId": "speakers",
        "summary": "The speakers A to Z (or by company) with their role, company, biography and sessions, a page at a time.",
        "parameters": [
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Words to find in the name, role, company and biography, in English or in the language asked.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "name (A to Z, the default) or company.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "dir",
            "in": "query",
            "required": false,
            "description": "asc (the default) or desc.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "How many to return, 1 to 100, default 25.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "How many matches to skip, default 0: 25 for the second page of 25.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "description": "en (the default), es, fr or de: the language of the text.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "total": {
                      "type": "integer"
                    },
                    "offset": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "speakers": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Speaker"
                      }
                    }
                  },
                  "required": [
                    "ok",
                    "total",
                    "offset",
                    "limit",
                    "count",
                    "speakers"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, wrong or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/public/v1/speakers/{slug}": {
      "get": {
        "tags": [
          "Public read"
        ],
        "operationId": "speaker",
        "summary": "One speaker.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "The speaker slug from /speakers, such as marco-dizon.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "description": "en (the default), es, fr or de: the language of the text.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "speaker": {
                      "$ref": "#/components/schemas/Speaker"
                    }
                  },
                  "required": [
                    "ok",
                    "speaker"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, wrong or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/public/v1/exhibitors": {
      "get": {
        "tags": [
          "Public read"
        ],
        "operationId": "exhibitors",
        "summary": "The exhibitors A to Z (or by booth), filtered by hall, product category and text, a page at a time.",
        "parameters": [
          {
            "name": "hall",
            "in": "query",
            "required": false,
            "description": "A or B.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "category",
            "in": "query",
            "required": false,
            "description": "loyalty, payments, fraud, data, travel, cx, marketing or mobile.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "q",
            "in": "query",
            "required": false,
            "description": "Words to find in the name, description, categories and booth.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sort",
            "in": "query",
            "required": false,
            "description": "name (A to Z, the default) or booth.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "dir",
            "in": "query",
            "required": false,
            "description": "asc (the default) or desc.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "limit",
            "in": "query",
            "required": false,
            "description": "How many to return, 1 to 100, default 25.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "offset",
            "in": "query",
            "required": false,
            "description": "How many matches to skip, default 0: 25 for the second page of 25.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "description": "en (the default), es, fr or de: the language of the text.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "total": {
                      "type": "integer"
                    },
                    "offset": {
                      "type": "integer"
                    },
                    "limit": {
                      "type": "integer"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "exhibitors": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Exhibitor"
                      }
                    }
                  },
                  "required": [
                    "ok",
                    "total",
                    "offset",
                    "limit",
                    "count",
                    "exhibitors"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, wrong or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/public/v1/exhibitors/{slug}": {
      "get": {
        "tags": [
          "Public read"
        ],
        "operationId": "exhibitor",
        "summary": "One exhibitor with its booth.",
        "parameters": [
          {
            "name": "slug",
            "in": "path",
            "required": true,
            "description": "The exhibitor slug from /exhibitors, such as nordvale.",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "description": "en (the default), es, fr or de: the language of the text.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "exhibitor": {
                      "$ref": "#/components/schemas/Exhibitor"
                    }
                  },
                  "required": [
                    "ok",
                    "exhibitor"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, wrong or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/public/v1/totals": {
      "get": {
        "tags": [
          "Public read"
        ],
        "operationId": "totals",
        "summary": "Live counts: confirmed registrations by pass, by day and by country, exhibitors, sponsors, booths and check-ins.",
        "parameters": [
          {
            "name": "days",
            "in": "query",
            "required": false,
            "description": "How many days of registrations by day, 1 to 90, default 14; the last day is today so far.",
            "schema": {
              "type": "integer"
            }
          },
          {
            "name": "lang",
            "in": "query",
            "required": false,
            "description": "en (the default), es, fr or de: the language of the text.",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "totals": {
                      "$ref": "#/components/schemas/Totals"
                    }
                  },
                  "required": [
                    "ok",
                    "totals"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, wrong or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/pod/v1/registrants/{id}": {
      "get": {
        "tags": [
          "Print on demand"
        ],
        "operationId": "podRegistrant",
        "summary": "Fetch a person",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Registration id or confirmation number",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "event",
            "in": "query",
            "required": false,
            "description": "Optional; any value other than ascent27 answers 404",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The record",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "record": {
                      "$ref": "#/components/schemas/PodRecord"
                    }
                  },
                  "required": [
                    "ok",
                    "record"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, wrong or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/pod/v1/registrants": {
      "get": {
        "tags": [
          "Print on demand"
        ],
        "operationId": "podRegistrants",
        "summary": "Records added or modified since a date-time",
        "parameters": [
          {
            "name": "since",
            "in": "query",
            "required": false,
            "description": "ISO 8601 date-time, inclusive",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "by",
            "in": "query",
            "required": false,
            "description": "modified (default) or added",
            "schema": {
              "type": "string",
              "enum": [
                "modified",
                "added"
              ]
            }
          },
          {
            "name": "event",
            "in": "query",
            "required": false,
            "description": "Optional; any value other than ascent27 answers 404",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The records, oldest first",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "since": {
                      "type": [
                        "string",
                        "null"
                      ]
                    },
                    "by": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    },
                    "records": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/PodRecord"
                      }
                    }
                  },
                  "required": [
                    "ok",
                    "since",
                    "by",
                    "count",
                    "records"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, wrong or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/pod/v1/registrants/{id}/printed": {
      "put": {
        "tags": [
          "Print on demand"
        ],
        "operationId": "podPrinted",
        "summary": "Mark printed or not printed (POST works the same)",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Registration id or confirmation number",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "printed": {
                    "type": "boolean"
                  }
                },
                "required": [
                  "printed"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Marked",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "id": {
                      "type": "string"
                    },
                    "printed": {
                      "type": "boolean"
                    },
                    "printedAt": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "ok",
                    "id",
                    "printed",
                    "printedAt"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, wrong or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/pod/v1/sessions": {
      "get": {
        "tags": [
          "Print on demand"
        ],
        "operationId": "podSessions",
        "summary": "Every session, with whether it takes check-in",
        "parameters": [
          {
            "name": "event",
            "in": "query",
            "required": false,
            "description": "Optional; any value other than ascent27 answers 404",
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The sessions",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "sessions": {
                      "type": "array",
                      "items": {
                        "allOf": [
                          {
                            "$ref": "#/components/schemas/PodSession"
                          },
                          {
                            "type": "object",
                            "properties": {
                              "checkIn": {
                                "type": "boolean"
                              }
                            },
                            "required": [
                              "checkIn"
                            ]
                          }
                        ]
                      }
                    }
                  },
                  "required": [
                    "ok",
                    "sessions"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, wrong or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/pod/v1/registrants/{id}/checkins": {
      "post": {
        "tags": [
          "Print on demand"
        ],
        "operationId": "podCheckIn",
        "summary": "Check a person in to a session",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Registration id or confirmation number",
            "schema": {
              "type": "string"
            }
          }
        ],
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "sessionId": {
                    "type": "string"
                  }
                },
                "required": [
                  "sessionId"
                ]
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "Already checked in",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "id": {
                      "type": "string"
                    },
                    "sessionId": {
                      "type": "string"
                    },
                    "booked": {
                      "type": "boolean"
                    },
                    "checkedInAt": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "ok",
                    "id",
                    "sessionId",
                    "booked",
                    "checkedInAt",
                    "status"
                  ]
                }
              }
            }
          },
          "201": {
            "description": "Checked in",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "id": {
                      "type": "string"
                    },
                    "sessionId": {
                      "type": "string"
                    },
                    "booked": {
                      "type": "boolean"
                    },
                    "checkedInAt": {
                      "type": "string"
                    },
                    "status": {
                      "type": "string"
                    }
                  },
                  "required": [
                    "ok",
                    "id",
                    "sessionId",
                    "booked",
                    "checkedInAt",
                    "status"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, wrong or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "409": {
            "description": "Check-in refused",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/pod/v1/registrants/{id}/checkins/{sessionId}": {
      "delete": {
        "tags": [
          "Print on demand"
        ],
        "operationId": "podUndoCheckIn",
        "summary": "Undo a check-in",
        "parameters": [
          {
            "name": "id",
            "in": "path",
            "required": true,
            "description": "Registration id or confirmation number",
            "schema": {
              "type": "string"
            }
          },
          {
            "name": "sessionId",
            "in": "path",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "Undone",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    }
                  },
                  "required": [
                    "ok"
                  ]
                }
              }
            }
          },
          "401": {
            "description": "Missing, wrong or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    },
    "/api/pod/v1/checkins": {
      "get": {
        "tags": [
          "Print on demand"
        ],
        "operationId": "podCheckins",
        "summary": "Who checked in to a session",
        "parameters": [
          {
            "name": "session",
            "in": "query",
            "required": true,
            "schema": {
              "type": "string"
            }
          }
        ],
        "responses": {
          "200": {
            "description": "The session and its check-ins",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "ok": {
                      "type": "boolean",
                      "const": true
                    },
                    "session": {
                      "$ref": "#/components/schemas/PodSession"
                    },
                    "checkins": {
                      "type": "array",
                      "items": {
                        "type": "object"
                      }
                    }
                  },
                  "required": [
                    "ok",
                    "session",
                    "checkins"
                  ]
                }
              }
            }
          },
          "400": {
            "description": "Bad input",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "401": {
            "description": "Missing, wrong or revoked key",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "404": {
            "description": "Not found",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          },
          "429": {
            "description": "Rate limit; see Retry-After",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Error"
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "apiKey": {
        "type": "apiKey",
        "in": "header",
        "name": "X-API-Key",
        "description": "The demo key ascent27_public_demo for the public read endpoints; Authorization: Bearer <key> works too."
      }
    },
    "schemas": {
      "Error": {
        "type": "object",
        "properties": {
          "ok": {
            "type": "boolean",
            "const": false
          },
          "error": {
            "type": "string"
          },
          "retryAfter": {
            "type": "integer"
          }
        },
        "required": [
          "ok",
          "error"
        ]
      },
      "SpeakerRef": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "role": {
            "type": "string"
          },
          "company": {
            "type": "string"
          },
          "url": {
            "type": "string"
          }
        },
        "required": [
          "slug",
          "name",
          "role",
          "company",
          "url"
        ]
      },
      "Event": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "shortName": {
            "type": "string"
          },
          "organiser": {
            "type": "string"
          },
          "fictional": {
            "type": "boolean"
          },
          "notice": {
            "type": "string"
          },
          "tagline": {
            "type": "string"
          },
          "summary": {
            "type": "string"
          },
          "startDate": {
            "type": "string",
            "format": "date"
          },
          "endDate": {
            "type": "string",
            "format": "date"
          },
          "start": {
            "type": "string"
          },
          "end": {
            "type": "string"
          },
          "timezone": {
            "type": "string"
          },
          "venue": {
            "type": "object",
            "properties": {
              "name": {
                "type": "string"
              },
              "city": {
                "type": "string"
              },
              "country": {
                "type": "string"
              },
              "countryName": {
                "type": "string"
              }
            },
            "required": [
              "name",
              "city",
              "country",
              "countryName"
            ]
          },
          "days": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "date": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                },
                "label": {
                  "type": "string"
                },
                "summary": {
                  "type": "string"
                }
              },
              "required": [
                "date",
                "name",
                "label",
                "summary"
              ]
            }
          },
          "passes": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string",
                  "enum": [
                    "full",
                    "day"
                  ]
                },
                "name": {
                  "type": "string"
                },
                "description": {
                  "type": "string"
                },
                "priceCents": {
                  "type": "integer"
                },
                "currency": {
                  "type": "string"
                },
                "points": {
                  "type": "integer"
                },
                "earlyRateUntil": {
                  "type": "string"
                },
                "days": {
                  "type": "array",
                  "items": {
                    "type": "string"
                  }
                },
                "labs": {
                  "type": "boolean"
                },
                "expo": {
                  "type": "boolean"
                }
              },
              "required": [
                "id",
                "name",
                "description",
                "priceCents",
                "currency",
                "points",
                "earlyRateUntil",
                "days",
                "labs",
                "expo"
              ]
            }
          },
          "url": {
            "type": "string"
          },
          "register": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "name",
          "shortName",
          "organiser",
          "fictional",
          "notice",
          "tagline",
          "summary",
          "startDate",
          "endDate",
          "start",
          "end",
          "timezone",
          "venue",
          "days",
          "passes",
          "url",
          "register"
        ]
      },
      "Session": {
        "type": "object",
        "properties": {
          "id": {
            "type": "string"
          },
          "day": {
            "type": "string"
          },
          "dayName": {
            "type": "string"
          },
          "dayLabel": {
            "type": "string"
          },
          "start": {
            "type": "string"
          },
          "end": {
            "type": [
              "string",
              "null"
            ]
          },
          "kind": {
            "type": "string",
            "enum": [
              "keynote",
              "session",
              "workshop",
              "social",
              "registration",
              "exhibits"
            ]
          },
          "title": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "room": {
            "type": "string"
          },
          "speakers": {
            "type": "array",
            "items": {
              "$ref": "#/components/schemas/SpeakerRef"
            }
          },
          "topics": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "name"
              ]
            }
          },
          "url": {
            "type": "string"
          }
        },
        "required": [
          "id",
          "day",
          "dayName",
          "dayLabel",
          "start",
          "end",
          "kind",
          "title",
          "description",
          "room",
          "speakers",
          "topics",
          "url"
        ]
      },
      "Speaker": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "role": {
            "type": "string"
          },
          "company": {
            "type": "string"
          },
          "bio": {
            "type": "string"
          },
          "photo": {
            "type": "string"
          },
          "sessions": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "title": {
                  "type": "string"
                },
                "start": {
                  "type": "string"
                },
                "url": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "title",
                "start",
                "url"
              ]
            }
          },
          "url": {
            "type": "string"
          }
        },
        "required": [
          "slug",
          "name",
          "role",
          "company",
          "bio",
          "photo",
          "sessions",
          "url"
        ]
      },
      "Exhibitor": {
        "type": "object",
        "properties": {
          "slug": {
            "type": "string"
          },
          "name": {
            "type": "string"
          },
          "description": {
            "type": "string"
          },
          "website": {
            "type": [
              "string",
              "null"
            ]
          },
          "categories": {
            "type": "array",
            "items": {
              "type": "object",
              "properties": {
                "id": {
                  "type": "string"
                },
                "name": {
                  "type": "string"
                }
              },
              "required": [
                "id",
                "name"
              ]
            }
          },
          "hall": {
            "type": [
              "string",
              "null"
            ]
          },
          "booth": {
            "type": [
              "string",
              "null"
            ]
          },
          "url": {
            "type": "string"
          }
        },
        "required": [
          "slug",
          "name",
          "description",
          "website",
          "categories",
          "hall",
          "booth",
          "url"
        ]
      },
      "Totals": {
        "type": "object",
        "properties": {
          "asOf": {
            "type": "string"
          },
          "registrations": {
            "type": "object",
            "properties": {
              "confirmed": {
                "type": "integer"
              },
              "countries": {
                "type": "integer"
              },
              "byPass": {
                "type": "object",
                "properties": {
                  "full": {
                    "type": "integer"
                  },
                  "day": {
                    "type": "integer"
                  },
                  "expo": {
                    "type": "integer"
                  }
                },
                "required": [
                  "full",
                  "day",
                  "expo"
                ]
              },
              "byDay": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "date": {
                      "type": "string"
                    },
                    "total": {
                      "type": "integer"
                    },
                    "full": {
                      "type": "integer"
                    },
                    "day": {
                      "type": "integer"
                    },
                    "expo": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "date",
                    "total",
                    "full",
                    "day",
                    "expo"
                  ]
                }
              },
              "byCountry": {
                "type": "array",
                "items": {
                  "type": "object",
                  "properties": {
                    "country": {
                      "type": "string"
                    },
                    "name": {
                      "type": "string"
                    },
                    "count": {
                      "type": "integer"
                    }
                  },
                  "required": [
                    "country",
                    "name",
                    "count"
                  ]
                }
              }
            },
            "required": [
              "confirmed",
              "countries",
              "byPass",
              "byDay",
              "byCountry"
            ]
          },
          "exhibitors": {
            "type": "integer"
          },
          "sponsors": {
            "type": "integer"
          },
          "booths": {
            "type": "object",
            "properties": {
              "total": {
                "type": "integer"
              },
              "sold": {
                "type": "integer"
              },
              "reserved": {
                "type": "integer"
              },
              "available": {
                "type": "integer"
              }
            },
            "required": [
              "total",
              "sold",
              "reserved",
              "available"
            ]
          },
          "checkIns": {
            "type": "object",
            "properties": {
              "people": {
                "type": "integer"
              },
              "today": {
                "type": "integer"
              },
              "sessionScans": {
                "type": "integer"
              }
            },
            "required": [
              "people",
              "today",
              "sessionScans"
            ]
          }
        },
        "required": [
          "asOf",
          "registrations",
          "exhibitors",
          "sponsors",
          "booths",
          "checkIns"
        ]
      },
      "PodSession": {
        "type": "object",
        "properties": {
          "sessionId": {
            "type": "string"
          },
          "title": {
            "type": "string"
          },
          "kind": {
            "type": "string"
          },
          "day": {
            "type": "string"
          },
          "start": {
            "type": [
              "string",
              "null"
            ]
          },
          "end": {
            "type": [
              "string",
              "null"
            ]
          },
          "location": {
            "type": [
              "string",
              "null"
            ]
          }
        },
        "required": [
          "sessionId",
          "title",
          "kind",
          "day",
          "start",
          "end",
          "location"
        ]
      },
      "PodRecord": {
        "type": "object",
        "description": "A person: see the record fields on the developer page.",
        "properties": {
          "id": {
            "type": "string"
          },
          "event": {
            "type": "string"
          },
          "confirmationNumber": {
            "type": [
              "string",
              "null"
            ]
          },
          "status": {
            "type": "string",
            "enum": [
              "draft",
              "pending_payment",
              "confirmed",
              "cancelled",
              "refunded"
            ]
          },
          "print": {
            "type": "boolean"
          },
          "noPrintReason": {
            "type": [
              "string",
              "null"
            ]
          },
          "printed": {
            "type": "boolean"
          },
          "printedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "attendance": {
            "type": "string"
          },
          "firstName": {
            "type": [
              "string",
              "null"
            ]
          },
          "lastName": {
            "type": [
              "string",
              "null"
            ]
          },
          "email": {
            "type": [
              "string",
              "null"
            ]
          },
          "jobTitle": {
            "type": [
              "string",
              "null"
            ]
          },
          "company": {
            "type": [
              "string",
              "null"
            ]
          },
          "city": {
            "type": [
              "string",
              "null"
            ]
          },
          "country": {
            "type": [
              "string",
              "null"
            ]
          },
          "phone": {
            "type": [
              "string",
              "null"
            ]
          },
          "registrationType": {
            "type": "string"
          },
          "registrationTypeId": {
            "type": "string"
          },
          "pass": {
            "type": "string"
          },
          "passId": {
            "type": "string"
          },
          "balanceDueCents": {
            "type": "integer"
          },
          "orderId": {
            "type": "string"
          },
          "isLead": {
            "type": "boolean"
          },
          "addedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "createdAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "modifiedAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "cancelledAt": {
            "type": [
              "string",
              "null"
            ]
          },
          "sessions": {
            "type": "array",
            "items": {
              "allOf": [
                {
                  "$ref": "#/components/schemas/PodSession"
                },
                {
                  "type": "object",
                  "properties": {
                    "source": {
                      "type": "string"
                    },
                    "checkedInAt": {
                      "type": [
                        "string",
                        "null"
                      ]
                    }
                  },
                  "required": [
                    "source",
                    "checkedInAt"
                  ]
                }
              ]
            }
          }
        }
      }
    }
  }
}