{
  "openapi": "3.0.0",
  "info": {
    "title": "Sporfie API",
    "description": "## Introduction\n\nThe Sporfie system exposes a set of REST APIs at **https://api.sporfie.com**.\n\nThese APIs allow you to\n\n- list Places\n- lookup Events\n- get detailed Event information\n- create/edit/delete Events\n- register/unregister for notification on Event changes\n- trigger the generation of highlight videos on an Event\n- manage collections of Bookmarks on Events\n\n### Essential concepts\n\n- An Event is a single occurrence of an activity that takes place at a specific period in time and at a specific location (e.g. a baseball game, a tennis match, a pickleball match, etc).\n- A Place is a location at which an Event occurs (e.g. a tennis court, a baseball field). Multiple events may be scheduled over time at the same Place, but only one Event can occur at a time on any given Place.\n\n## Authentication\n\nThis API will only answer to authenticated requests from a Backend service.\n\nYou must never call this API from a WebApp.\n\nA request is authenticated by adding the token we have given you in the HTTP request header:\n\n`Authorization: Bearer {token}`\n\nThis token must remain secret and must never be exposed to the public (e.g. in a WebApp).\n\n## MCP server (AI agents)\n\nAgents that speak the Model Context Protocol can use this API without writing HTTP calls: connect to **https://mcp.sporfie.com/mcp** (Streamable HTTP) with the same bearer token in the `Authorization` header, and work through 19 curated tools — events, discovery, highlight moments, webhooks — plus anonymous Sporfie Help Center search for support questions.\n\nClaude Code:\n\n`claude mcp add --transport http sporfie https://mcp.sporfie.com/mcp --header \"Authorization: Bearer {token}\"`\n\nAgent-oriented details: [docs.sporfie.com/agents](https://docs.sporfie.com/agents).",
    "version": "1.7.1",
    "x-logo": {
      "url": "https://docs.sporfie.com/logo.png",
      "backgroundColor": "#475355"
    }
  },
  "tags": [
    {
      "name": "Sport data",
      "description": "Retrieval of Sport data"
    },
    {
      "name": "Place data",
      "description": "Retrieval of Place data"
    },
    {
      "name": "Event data",
      "description": "Retrieval of Event data"
    },
    {
      "name": "Event Watch",
      "description": "Observing changes in Events"
    },
    {
      "name": "Moment data",
      "description": "Retrieval and management of Moment data"
    },
    {
      "name": "Video generation",
      "description": "Generation of highlight videos"
    },
    {
      "name": "Bookmark management",
      "description": "Manage Bookmark Collections in Events"
    },
    {
      "name": "Reel management",
      "description": "Manage Reels of a Company/Organization"
    },
    {
      "name": "Scope data",
      "description": "Retrieval of Scope data"
    }
  ],
  "servers": [
    {
      "url": "https://api.sporfie.com"
    }
  ],
  "security": [
    {
      "bearerAuth": []
    }
  ],
  "paths": {
    "/public/places": {
      "parameters": [
        {
          "schema": {
            "type": "string"
          },
          "in": "query",
          "name": "companyKey",
          "description": "The company/organization's key",
          "required": true
        }
      ],
      "get": {
        "summary": "Places",
        "tags": ["Place data"],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "description": "",
                  "type": "object",
                  "properties": {
                    "places": {
                      "type": "array",
                      "items": {
                        "$ref": "#/components/schemas/Place"
                      }
                    }
                  },
                  "required": ["page", "pageSize", "totalCount", "events"]
                }
              }
            }
          },
          "404": {
            "description": "Not Found"
          }
        },
        "operationId": "Get Places of a Company/Organization",
        "description": "This end point returns all the Places of the targeted Company/organization"
      }
    },
    "/public/places/{placeKey}/score": {
      "parameters": [
        {
          "schema": {
            "type": "string"
          },
          "name": "placeKey",
          "in": "path",
          "required": true,
          "description": "The key of the place to add the score to"
        }
      ],
      "post": {
        "summary": "Add a score entry in the score stream",
        "tags": ["Place data"],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "eventKey": {
                      "type": "string",
                      "description": "The unique identifier of the event on which the score entry has been added"
                    },
                    "key": {
                      "type": "string",
                      "description": "The unique identifier of the score stream entry"
                    },
                    "warning": {
                      "type": "string",
                      "description": "In case no event is currently running on the place, a warning message indicating that the score data has been dropped is returned in this field. In that case, the `eventKey` and `key` fields are not returned."
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found"
          }
        },
        "operationId": "Add score on place",
        "description": "Add a score entry in the score stream of the current event running on the specified place.\n\nIf no event is currently running on the place, the score data is **dropped** and a warning message is returned instead of the event and score stream entry keys.\n\n`placeKey` is the Sporfie-generated place key.\n",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "timeStamp": {
                    "type": "integer",
                    "description": "Absolute time of the score information (UTC, unix epoch in milliseconds)"
                  }
                },
                "required": ["timeStamp"]
              }
            }
          },
          "description": "The Score information may be specific to the sport of the event. See the entry for adding a score entry in the Event data endpoint for more details."
        }
      }
    },
    "/public/event-lookup-by-place-and-time": {
      "get": {
        "summary": "Event lookup by place and time",
        "tags": ["Event data"],
        "description": "Finds a specific Sporfie Event for a given place and time. \n\nThe end point looks for the event that started after, and within one hour of, the given date and time and returns its unique identifier.\nIf there are several matching events (multiple events on that place within the same hour), the key of the first one is returned.\n\n**Important**: the date & time information must be given in UTC, not local time.",
        "operationId": "event-lookup",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "eventKey": {
                      "type": "string",
                      "description": "The Sporfie internal identifier of the event for that place at that time"
                    }
                  },
                  "required": ["eventKey"]
                }
              }
            }
          }
        },
        "parameters": [
          {
            "schema": {
              "type": "string",
              "example": "Place_345"
            },
            "in": "query",
            "name": "placeKey",
            "description": "The Place identifier",
            "required": true
          },
          {
            "schema": {
              "type": "number",
              "example": 2021
            },
            "in": "query",
            "name": "year",
            "description": "The year the event started (UTC)",
            "required": true
          },
          {
            "schema": {
              "type": "integer",
              "maximum": 12,
              "example": 5,
              "minimum": 1
            },
            "in": "query",
            "name": "month",
            "description": "The month the event started (UTC)",
            "required": true
          },
          {
            "schema": {
              "type": "integer",
              "maximum": 31,
              "example": 6,
              "minimum": 1
            },
            "in": "query",
            "name": "day",
            "description": "The day the event started (UTC)",
            "required": true
          },
          {
            "schema": {
              "type": "integer",
              "minimum": 0,
              "maximum": 23,
              "example": 16
            },
            "in": "query",
            "name": "hour",
            "description": "The hour the event started (UTC)",
            "required": true
          }
        ]
      },
      "parameters": []
    },
    "/public/places/{placeKey}/activeEventKey": {
      "parameters": [
        {
          "schema": {
            "type": "string"
          },
          "name": "placeKey",
          "in": "path",
          "required": true
        }
      ],
      "get": {
        "summary": "Active Event on Place",
        "tags": ["Event data"],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "activeEventKey": {
                      "type": "string",
                      "description": "The key of the event currently active on the place"
                    }
                  },
                  "required": ["activeEventKey"]
                }
              }
            }
          },
          "404": {
            "description": "Not Found"
          }
        },
        "operationId": "get-public-places-placeKey-activeEventKey",
        "description": "Returns the key of the event currently active on the given place.\n\nIf no event is currently active on that place a 404 is returned instead."
      }
    },
    "/public/event-search-by-company": {
      "get": {
        "summary": "Event search by company/organization",
        "tags": ["Event data"],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "description": "",
                  "type": "object",
                  "x-examples": {
                    "example-1": {
                      "page": 0,
                      "pageSize": 1,
                      "totalCount": 2,
                      "events": [
                        {
                          "key": "string",
                          "externalEventID": "string",
                          "name": "string",
                          "creationDate": 1234556,
                          "scheduledStartTime": 13271653721
                        }
                      ]
                    }
                  },
                  "properties": {
                    "page": {
                      "type": "number",
                      "description": "The current page. The first page is page 0."
                    },
                    "pageSize": {
                      "type": "number",
                      "description": "The page size"
                    },
                    "totalCount": {
                      "type": "number",
                      "description": "The total number of events corresponding to the search criteria"
                    },
                    "events": {
                      "type": "array",
                      "uniqueItems": true,
                      "minItems": 1,
                      "description": "The list of events",
                      "items": {
                        "$ref": "#/components/schemas/EventShort"
                      }
                    }
                  },
                  "required": ["page", "pageSize", "totalCount", "events"]
                }
              }
            }
          }
        },
        "operationId": "event-search",
        "description": "Finds events belonging to a given company/organization and having a given state.\n\nThe results are paginated and include a trimmed-down representation of found events. For the full event data about a particular event, a separate request should be made on the Event data endpoint with the event key retrieved from this list.\n\n### Event states\nThree event states are supported:\n- `future` - the event has not started yet\n- `current` - the event has started but not finished yet\n- `past` - the event has finished\n\n### Event ordering\nThe order of events in the response depends on the state of the events:\n- `future` - increasing order of scheduled start time\n- `current` - increasing order of start time\n- `past` - decreasing order of start time",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "companyKey",
            "description": "The company/organization's key",
            "required": true
          },
          {
            "schema": {
              "type": "string",
              "enum": ["future", "current", "past"]
            },
            "in": "query",
            "name": "state",
            "description": "The state of the event",
            "required": true
          },
          {
            "schema": {
              "type": "number"
            },
            "in": "query",
            "name": "pageSize",
            "description": "The number of events to return per page",
            "required": true
          },
          {
            "schema": {
              "type": "number"
            },
            "in": "query",
            "name": "page",
            "description": "The page number. The first page is page 0.",
            "required": true
          }
        ]
      }
    },
    "/public/events/{eventKey}": {
      "parameters": [
        {
          "schema": {
            "type": "string"
          },
          "name": "eventKey",
          "in": "path",
          "required": true,
          "description": "The event externalID or eventKey"
        }
      ],
      "get": {
        "summary": "Event data",
        "tags": ["Event data"],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Event"
                }
              }
            }
          },
          "404": {
            "description": "Not Found"
          }
        },
        "operationId": "Get event data",
        "description": "This end point returns all the relevant data for the given event key.\n\n**Note** event data changes over time as the event unfolds, e.g. live streams are started and stopped, moments are captured, etc.\n\nThis API returns a snapshot of the event data at the time of the request. To stay informed of changes in the event data, use the Watch API.\n\n`eventKey` may either be a Sporfie-internal event key, or an event's `externalID`."
      },
      "delete": {
        "summary": "",
        "operationId": "Delete event",
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not Found"
          },
          "417": {
            "description": "Expectation Failed - if the event is still running"
          }
        },
        "description": "Deletes an event.\n\n`eventKey` may either be a Sporfie-internal event key, or an event's `externalID`.\n\nAn event may only be deleted if it is not currently running (has started and has not yet ended).",
        "tags": ["Event data"]
      },
      "post": {
        "summary": "",
        "operationId": "Create event",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "eventKey": {
                      "type": "string",
                      "description": "The Sporfie event key. May be used in place of the event's externalID."
                    }
                  },
                  "required": ["eventKey"]
                }
              }
            }
          },
          "400": {
            "description": "Bad Request - In case one or more of the fields have unacceptable values"
          },
          "403": {
            "description": "Forbidden"
          },
          "409": {
            "description": "Conflict - the provided `event_key` is already used as an `externalID` in an existing event previously created by your system."
          }
        },
        "description": "Creates an event in the Sporfie database.\n\nThe event's `externalID` is set to the value of the `eventKey` parameter. Upon successful event creation, the event's internal ID is returned in the response in the `eventKey` field. The event may thereafter be referred to either by its `externalID` or its internal `eventKey`.\n\nYou are free to choose your external ID as you see fit, within the following constraints:\n- ASCII characters in the character set \\[-_0-9a-zA-Z\\]\n- maximum length of 64 bytes\n- unique and not already used in the context of your access to this system\n\nOnly the `name` and `location` fields are mandatory in the body data, if `placeKey` is not set. If `placeKey` is set, `location` field is optional because the location will be inherited from the place. `name` may not be empty.\n\nThe `sport` field must be one of the sport codes returned by the `GET /public/sports` endpoint. If `sport` is not provided and the event is created on a Place (i.e. `placeKey` is set), the Place's sport will be used; otherwise, `other` will be used.\n\nIf `placeKey` is present, then so must `scheduledStartTime` and `scheduledEndTime`.\n\nWhen provided, `scheduledStartTime` and `scheduledEndTime` **must both be present** and be in the future and `scheduledEndTime` must be greater than `scheduledStartTime` by at least 5 minutes.\n\nThe `thumbnailURL` must point to a publicly accessible image resource. The image is copied by the Sporfie system and may be resized or cropped to fit Sporfie's requirements.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EventCreate"
              }
            }
          }
        },
        "tags": ["Event data"]
      },
      "patch": {
        "summary": "",
        "operationId": "Modify event",
        "responses": {
          "200": {
            "description": "OK"
          },
          "400": {
            "description": "Bad Request - In case one or more of the fields have unacceptable values"
          },
          "403": {
            "description": "Forbidden"
          },
          "404": {
            "description": "Not Found"
          }
        },
        "description": "Modifies an existing event.\n\n`eventKey` may either be a Sporfie-internal event key, or an event's `externalID`.\n\nNo field is mandatory in the body data. Only fields present in the body data will be updated in the event, other fields will be left unmodified. The `location` and `metadata` fields are considered as atomic values in that respect.\n\nWhen present, `scheduledStartTime` and `scheduledEndTime` must be in the future.\nCurrent values of `scheduledStartTime` and `scheduledEndTime` must be in the future to be modifiable.\nThe value of `placeKey` may not be modified if `scheduledStartTime` is in the past.\n\nThe `thumbnailURL` must point to a publicly accessible image resource. The image is copied by the Sporfie system and may be resized or cropped to fit Sporfie's requirements.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/EventCreate"
              }
            }
          }
        },
        "tags": ["Event data"]
      }
    },
    "/public/events/{eventKey}/close": {
      "parameters": [
        {
          "schema": {
            "type": "string"
          },
          "name": "eventKey",
          "in": "path",
          "required": true
        }
      ],
      "post": {
        "summary": "Close an event",
        "tags": ["Event data"],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not Found"
          }
        },
        "operationId": "Close an event",
        "description": "Immediately closes an event.\n\n\nWhen an event is closed, its live streams stop and no new clips are generated."
      }
    },
    "/public/events/{eventKey}/score": {
      "parameters": [
        {
          "schema": {
            "type": "string"
          },
          "name": "eventKey",
          "in": "path",
          "required": true,
          "description": "The key of the event to add the score to"
        }
      ],
      "post": {
        "summary": "Add a score entry in the score stream",
        "tags": ["Event data"],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "key": {
                      "type": "string",
                      "description": "The unique identifier of the score stream entry"
                    }
                  },
                  "required": ["key"]
                }
              }
            }
          },
          "404": {
            "description": "Not Found"
          }
        },
        "operationId": "Add score",
        "description": "Add a score entry in the score stream of the event.\n\n`eventKey` may either be a Sporfie-internal event key, or an event's `externalID`.\n",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "timeStamp": {
                    "type": "integer",
                    "description": "Absolute time of the score information (UTC, unix epoch in milliseconds)"
                  }
                },
                "required": ["timeStamp"]
              }
            }
          },
          "description": "The score information at `timeStamp`. \n\nThe `score` object may contain any score information that is relevant for the sport of the event. It must contain a `timeStamp` field.\n\nThe generic score format includes the following fields\n- `left`: integer, the score of the 'left' player (typically Home)\n- `period`: integer, the current period (e.g. first half, or second set, etc...)\n- `right`: integer, the score of the 'right' player (typically Away)\n\nPlease ask for details about your sport.\n\n**The `timeStamp` and `key` fields are reserved field names in the score object**.\n\n\n### Sport-specific Score Formats\n\n#### Tennis\nThe `scoreValue` object contains two components: `gameScores` and `pointScore`.\n- `gameScores` is an array of pairs representing sets, where each pair contains games won by home and away teams.\n- `pointScore` is a pair representing the point total in the current game. Instead of 15, 30, 40, A, the values 1, 2, 3, and 4 are used, respectively.\nEven though `left`, `right`, and `period` are not used in scoring, they must be present.\n\n#### Volleyball\nThe `scoreValue` object contains only `gameScores`, which functions similarly to Tennis but without `pointScore`.\n- Each pair in `gameScores` represents a set, where values indicate the points won by the home and away teams.\n- The logic for determining a set win differs from Tennis, based on volleyball-specific rules.\n\n**Example - Volleyball Score Update**\n\n```json\n{\n  \"period\": 0,\n  \"right\": -1,\n  \"left\": -1,\n  \"timeStamp\": 1692319468961,\n  \"scoreValue\": {\n    \"gameScores\": [[25, 22], [19, 25], [25, 20]]\n  }\n}\n```"
        }
      }
    },
    "/public/events/{eventKey}/score/{scoreKey}": {
      "parameters": [
        {
          "schema": {
            "type": "string"
          },
          "name": "eventKey",
          "in": "path",
          "required": true,
          "description": "The key of the event to remove the score from"
        },
        {
          "schema": {
            "type": "string"
          },
          "name": "scoreKey",
          "in": "path",
          "required": true,
          "description": "The key of the score entry"
        }
      ],
      "delete": {
        "summary": "Delete a score entry",
        "tags": ["Event data"],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not Found"
          }
        },
        "operationId": "Delete a score entry",
        "description": "Delete a score entry from the score stream."
      }
    },
    "/public/events/{eventKey}/watch": {
      "parameters": [
        {
          "schema": {
            "type": "string"
          },
          "name": "eventKey",
          "in": "path",
          "required": true,
          "description": "The key of the event to watch"
        }
      ],
      "put": {
        "summary": "Watch an event",
        "tags": ["Event Watch"],
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not Found"
          }
        },
        "operationId": "watch",
        "description": "Register for notification on event changes.\n\nCall this end point when you need to be notified of changes on a specific event.\n\n`eventKey` may either be a Sporfie-internal event key, or an event's `externalID`.\n\nOnce registered, your webhook will be called whenever anything changes in the event. A change to any of the following event properties will trigger a callback\n\n- event info (name, location, sport, pin codes, teams, start date, end date, organization, public pages, tags)\n- moment addition or state change (e.g. new video)\n- highlights video addition\n- media file (full event recording) addition or update\n- live stream changes\n\nYour webhook is called with the updated event data:\n\n```\nPOST {webhook}\n{\n   ... // Event data, in the same format as returned by the Event data end point\n}\n```\n\nThis registration call is idempotent, calling it several times will register only one webhook for a given event and any previously registered webhook will be replaced with the new one.\n\nWhen you don't need to be notified of updates anymore, call the same endpoint with the `DELETE` verb to unregister.\n\n**Important**: the registration is valid for a maximum of 12 hours, after which your webhook will be unregistered. To maintain your webhook, you must re-register it within that time limit.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/WebHook"
              }
            }
          },
          "description": ""
        }
      },
      "delete": {
        "summary": "Stop watching an event",
        "tags": ["Event Watch"],
        "operationId": "unwatch",
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not Found"
          }
        },
        "description": "Call this endpoint to unregister from notifications on a given Event.\n\n`event_key` may either be a Sporfie-internal event key, or an event's `externalID`."
      }
    },
    "/public/overlay-preview": {
      "post": {
        "summary": "Video Overlay Preview",
        "tags": ["Video generation"],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "videoURL": {
                      "type": "string",
                      "description": "The output video URL"
                    }
                  },
                  "required": ["videoURL"]
                }
              }
            }
          }
        },
        "operationId": "overlay-preview",
        "description": "Use this end point to validate your overlay templates.\n\nYou can specify a source video to use using `sourceURL` or use our default test video by not providing a `sourceURL`.\n\nThe source video is trimmed down to 15 seconds.\n\nYour overlays will be applied to the video and the resulting video's URL is returned in the answer to the call. The video is available for 1 hour at that URL.\n\nThe video generation process takes about 30 seconds (up to a minute on the first call) to complete.\n\n**All time values in this endpoint are expressed in milliseconds.** In particular, each overlay's `startTime` and `duration` are in milliseconds (relative to the start of the video clip).\n",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "type": "object",
                "properties": {
                  "sourceURL": {
                    "type": "string",
                    "description": "The video on which to test your overlays. This must point to a freely downloadable MP4 video."
                  },
                  "overlays": {
                    "type": "array",
                    "items": {
                      "$ref": "#/components/schemas/Overlay"
                    }
                  }
                },
                "required": ["overlays"]
              },
              "examples": {}
            }
          }
        }
      }
    },
    "/public/events/{eventKey}/clicks": {
      "post": {
        "summary": "Click",
        "tags": ["Video generation"],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "momentKey": {
                      "type": "string",
                      "description": "The identifier of the new Moment created for that click"
                    }
                  },
                  "required": ["momentKey"]
                }
              }
            }
          },
          "206": {
            "description": "Partial content - The click was performed but some of the data were not accepted, typically the metadata is too large or contains data we cannot store.",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "momentKey": {
                      "type": "string",
                      "description": "The identifier of the new Moment created for that click"
                    },
                    "error": {
                      "type": "string",
                      "description": "An error message indicating the problem with the data received"
                    }
                  },
                  "required": ["momentKey"]
                }
              }
            }
          }
        },
        "operationId": "click",
        "description": "Creates a Click and triggers the recording of a Moment with video clips.\n\nThe behavior of this endpoint differs based on the state of the Event. If the Event is still open, then all currently active cameras generate a video clip for the requested time range and upload it to the Sporfie system to create a multi-angle Moment. Beware that only the last minute of content is available for generating video clips while the Event is open.\n\nHowever, if the Event is no longer open (i.e. Event has an `endTime`), then all the uploaded content becomes available for generating video clips. The Sporfie system will use all the available Media Files to create a single multi-angle Moment, using the requested time range from each Media File, if available.\n\n`eventKey` may either be a Sporfie-internal event key, or an event's `externalID`.\n\n**All time values in this endpoint are expressed in milliseconds.** Specifically, the Click's `timeStamp`, `startTime`, and `endTime`, as well as the inner `score.timeStamp`, are absolute times in UTC milliseconds since the Unix epoch. Each overlay's `startTime` and `duration` are also in milliseconds (relative to the start of the video clip).\n\nIf no `startTime` and `endTime` are provided, the default settings for the event's sport are used to compute a recording window.\n\nThe `score` field is an unconstrained dictionary containing the score information for that moment in time. It is stored as is and will appear at that time stamp in the event's score stream.\n\nThe `players` field is optional and lists the players involved in the Moment. When present, this information is used by the Sporfie WebApp to allow the user to filter Moments by player on the Event page.\n\nThe `metadata` field is an optional dictionary that may be used by the caller to store any custom information he/she may want to associate with the Moment. It is stored as is in the Moment generated by the click. See the description of the field for restrictions on the content of this dictionary.\n\nThe generated video clips may be augmented with overlays. The list of overlays to apply is passed in `overlays`. See the definition of Overlay for details. All clips have the same overlays.\n\n**Note** retrieving the clips and applying the overlays takes a few seconds. Getting a positive response from the server does not indicate that the videos are available, only that the request has been accepted and that the process of generating the videos is under way.\n\n### Overlays\n\nAn Overlay is a still picture burned into a video clip at a fixed location with a fixed size starting at a given time and for a given duration.\n\n#### Overlay image\n\nThere are two ways to provide the picture to be burned in\n\n- a URL to a valid PNG or JPG file\n- a URL to an HTML template and a matching list of values for placeholders found in the HTML template\n\n##### Image url\n\nThe `imageSource` url must point to a freely accessible and valid PNG or JPEG file. When burned into the video, the aspect ratio of the image is maintained.\n\n##### Template\n\nThe `templateSource` url must point to a freely accessible and valid HTML file.\n\nThe HTML may contain any number of placeholders that shall be replaced by values found in the `values` dictionary.\n\nThe template must meet the following requirements:\n\n- a `meta` entry specifying the natural rendering size for the scoreboard **must** be present in the file `<meta renderWidth=\"410\" renderHeight=\"27\"/>`. The rendered overlay will have the specified size. Note that this is not the final size that the overlay will have in the video, that size is specified by `heightPercentOfHeight` (see below).\n- all CSS must be included in the HTML file in `<style>` entries\n- no `<script>` entry is permitted\n- placeholders in the template shall be framed with square brackets so as to ensure proper replacement without interference with the rest of the HTML. For instance the placeholder `text1` shall be used in the HTML as `[text1]`, e.g. `<div>[text1]</div>`.\n- The keys of the `values` dictionary are the names of the placeholders, without the brackets, e.g. `{ \"text1\": \"Training session\" }`. All placeholders found in the template **must** have a value in the `values` dictionary (which can be an empty string if needed).\n- to allow for round corners and visually separated elements, the template is rendered over a transparent background, so `<body>` must be given a `background-color` if one does not want a transparent background.\n- external fonts may be referenced in `<style>` entries as `@font-face`, e.g.\n\n```\n      @font-face {\n        font-family: 'Roboto';\n        font-style: normal;\n        font-weight: 400;\n        src: url(https://fonts.gstatic.com/s/roboto/v27/KFOmCnqEu92Fr1Me5Q.ttf) format('truetype');\n      }\n```\n\nThe downloaded template and the `values` are used to generate a PNG image, which is then burned into the video at the given location and time.\n\nHere is a sample template:\n\n```\n<!DOCTYPE html>\n<html lang=\"en\">\n  <head>\n    <meta charset=\"utf-8\" />\n    <meta renderWidth=\"410\" renderHeight=\"27\" />\n    <style>\n      @font-face {\n        font-family: 'Roboto';\n        font-style: normal;\n        font-weight: 400;\n        src: url(https://fonts.gstatic.com/s/roboto/v27/KFOmCnqEu92Fr1Me5Q.ttf) format('truetype');\n      }\n      body {\n        width: 100vw;\n        height: 100vh;\n        margin: 0;\n        overflow: hidden;\n        font-family: 'Roboto';\n      }\n      .Score {\n        background-color: white;\n        color: black;\n        font-size: 20px;\n        text-align: center;\n      }\n      .team {\n        font-size: 80%;\n        display: inline-block;\n        padding: 0.1em 0.4em;\n        background-color: white;\n        color: black;\n        vertical-align: middle;\n        width: 5em;\n        white-space: nowrap;\n        overflow: hidden;\n        text-overflow: ellipsis;\n        text-transform: uppercase;\n      }\n      .score {\n        font-weight: bold;\n        display: inline-block;\n        padding: 0.1em 0.4em;\n        background-color: black;\n        color: white;\n        vertical-align: middle;\n        min-width: 2em;\n      }\n      .period {\n        display: inline-block;\n        padding: 0.2em 1em;\n        height: 100%;\n        font-size: 65%;\n        font-weight: bold;\n        vertical-align: middle;\n        min-width: 2em;\n      }\n    </style>\n  </head>\n  <body>\n    <div class=\"Score\">\n      <div class=\"team\">[home_team]</div>\n      <div class=\"score\">[left]</div>\n      <div class=\"period\">[period]</div>\n      <div class=\"score\">[right]</div>\n      <div class=\"team\">[away_team]</div>\n    </div>\n  </body>\n</html>\n\n```\n\n#### Placement and sizing\n\nThe overlay image is placed in the position specified by `position`:\n\n```\nposition: {\n  horizontal: 'left' | 'center' | 'right',\n  vertical: 'top' | 'center' | 'bottom'\n}\n```\n\nFor instance:\n\n```\n{\n  ...\n  \"position\": { \"horizontal\": \"left\", \"vertical\": \"center\" }\n  ...\n}\n```\n\nwill position the overlay on the left side of the video, vertically centered.\n\nThe size of the image in the video is defined by the `heightPercentOfHeight` or `widthPercentOfWidth` parameter, which specifies the height or width of the image in percent of the height or width of the video. Exactly one of the two parameters must be specified, the other dimension is computed according to the aspect ratio of the image. If both parameters are present, `heightPercentOfHeight` takes precedence.\n\nWhen the overlay is placed in a corner or a side, a margin is added vertically and horizontally to detach the overlay from the border of the video. The size of this margin (both horizontally and vertically) is a percentage of the video's width (`marginPercentOfWidth`) or height (`marginPercentOfHeight`), either one parameter may be specified, but not both. If both are present, `marginPercentOfHeight` takes precedence.\n\n#### Placement in time\n\nUnless specified otherwise, the overlay is shown from the start to the end of the video.\n\nThe `startTime` and `duration` parameters allow to time the display of the overlay more precisely.\n",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/Click"
              }
            }
          }
        }
      },
      "parameters": [
        {
          "schema": {
            "type": "string"
          },
          "name": "eventKey",
          "in": "path",
          "required": true,
          "description": "The event key"
        }
      ]
    },
    "/public/moments/{momentKey}": {
      "parameters": [
        {
          "schema": {
            "type": "string"
          },
          "name": "momentKey",
          "in": "path",
          "required": true,
          "description": "The moment key"
        }
      ],
      "get": {
        "summary": "Moment",
        "tags": ["Moment data"],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/MomentSingle"
                }
              }
            }
          },
          "404": {
            "description": "Not Found"
          }
        },
        "operationId": "Get a Moment",
        "description": "This end point returns the data for a given Moment."
      },
      "patch": {
        "summary": "",
        "tags": ["Moment data"],
        "responses": {
          "200": {
            "description": "OK"
          },
          "206": {
            "description": "Partial content - The moment was updated but some of the changes could not be applied, typically the metadata is too large or contains data we cannot store."
          },
          "400": {
            "description": "Bad Request - In case one or more of the fields have unacceptable values"
          },
          "403": {
            "description": "Forbidden"
          },
          "404": {
            "description": "Not Found"
          }
        },
        "operationId": "Update moment data",
        "description": "Modifies some properties of a moment.\n\nNo field is mandatory in the body data. Only fields present in the body data will be updated in the moment, other fields will be left unmodified.",
        "requestBody": {
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/MomentUpdate"
              }
            }
          }
        }
      },
      "delete": {
        "summary": "Delete a Moment",
        "tags": ["Moment data"],
        "responses": {
          "200": {
            "description": "OK"
          },
          "403": {
            "description": "Forbidden"
          },
          "404": {
            "description": "Not Found"
          }
        },
        "operationId": "Delete a Moment",
        "description": "Deletes a moment and all its associated video clips.\n\nThe linked score stream entry is not deleted.\n\nIf the moment is still processing (i.e. video clips are being generated), the delete will still succeed."
      }
    },
    "/public/moments/{momentKey}/clips/{clipKey}": {
      "parameters": [
        {
          "schema": {
            "type": "string"
          },
          "name": "momentKey",
          "in": "path",
          "required": true,
          "description": "The moment key"
        },
        {
          "schema": {
            "type": "string"
          },
          "name": "clipKey",
          "in": "path",
          "required": true,
          "description": "The video clip key (from the `key` field in the moment's `videoClips` array)"
        }
      ],
      "delete": {
        "summary": "Delete a Video Clip",
        "tags": ["Moment data"],
        "responses": {
          "200": {
            "description": "OK"
          },
          "403": {
            "description": "Forbidden"
          },
          "404": {
            "description": "Not Found"
          }
        },
        "operationId": "Delete a Video Clip",
        "description": "Deletes a single video clip from a moment.\n\nThe parent moment is not deleted even if it has no remaining video clips after this operation."
      }
    },
    "/public/bookmark-collections/events/{eventKey}": {
      "parameters": [
        {
          "schema": {
            "type": "string"
          },
          "name": "eventKey",
          "in": "path",
          "required": true,
          "description": "The event key"
        }
      ],
      "get": {
        "summary": "Bookmark Collections of Event",
        "tags": ["Bookmark management"],
        "operationId": "get-bookmark-collections-of-event",
        "description": "Returns the Bookmark Collections of the given Event. Includes public collections and those owned by the requester.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "bookmarkCollections": {
                      "type": "object",
                      "additionalProperties": {
                        "$ref": "#/components/schemas/BookmarkCollection"
                      }
                    }
                  },
                  "example": {
                    "bookmarkCollections": {
                      "collection1": {
                        "name": "string",
                        "isPublic": true,
                        "eventKey": "string",
                        "mediaFileKey": "string",
                        "userID": "string",
                        "externalSystemID": "string",
                        "shortURL": "string",
                        "bookmarks": {
                          "bookmark1": {
                            "startTime": 0,
                            "endTime": 0,
                            "tag": "string",
                            "comment": "string",
                            "thumbnailURL": "string",
                            "shortURL": "string"
                          },
                          "bookmark2": {
                            "startTime": 0,
                            "endTime": 0,
                            "tag": "string",
                            "comment": "string",
                            "thumbnailURL": "string",
                            "shortURL": "string"
                          }
                        },
                        "exports": {
                          "export1": {
                            "status": "string",
                            "videoURL": "string",
                            "thumbnailURL": "string",
                            "error": "string"
                          }
                        }
                      },
                      "collection2": {
                        "name": "string",
                        "isPublic": true,
                        "eventKey": "string",
                        "mediaFileKey": "string",
                        "userID": "string",
                        "externalSystemID": "string",
                        "shortURL": "string",
                        "bookmarks": {
                          "bookmark3": {
                            "startTime": 0,
                            "endTime": 0,
                            "tag": "string",
                            "comment": "string",
                            "thumbnailURL": "string",
                            "shortURL": "string"
                          }
                        },
                        "exports": {}
                      }
                    }
                  },
                  "required": ["bookmarkCollections"]
                }
              }
            }
          },
          "404": {
            "description": "Not Found"
          }
        }
      },
      "post": {
        "summary": "Create Bookmark Collection for Event",
        "tags": ["Bookmark management"],
        "operationId": "create-bookmark-collection-for-event",
        "description": "Creates a Bookmark Collection attached to the Event.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BookmarkCollectionCreationRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "bookmarkCollectionKey": {
                      "type": "string",
                      "description": "The key of the newly created Bookmark Collection"
                    }
                  },
                  "required": ["bookmarkCollectionKey"]
                }
              }
            }
          },
          "400": {
            "description": "Bad Request"
          },
          "404": {
            "description": "Not Found"
          }
        }
      }
    },
    "/public/bookmark-collections/events/{eventKey}/{userID}": {
      "parameters": [
        {
          "schema": {
            "type": "string"
          },
          "name": "eventKey",
          "in": "path",
          "required": true,
          "description": "The event key"
        },
        {
          "schema": {
            "type": "string"
          },
          "name": "userID",
          "in": "path",
          "required": true,
          "description": "User ID to filter collections by owner"
        }
      ],
      "get": {
        "summary": "Bookmark Collections of Event by User",
        "tags": ["Bookmark management"],
        "operationId": "get-bookmark-collections-of-event-by-user",
        "description": "Returns the Bookmark Collections of the given Event that are owned by the specified user.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "bookmarkCollections": {
                      "type": "object",
                      "additionalProperties": {
                        "$ref": "#/components/schemas/BookmarkCollection"
                      }
                    }
                  },
                  "required": ["bookmarkCollections"],
                  "example": {
                    "bookmarkCollections": {
                      "collection1": {
                        "name": "string",
                        "isPublic": true,
                        "eventKey": "string",
                        "mediaFileKey": "string",
                        "userID": "string",
                        "externalSystemID": "string",
                        "shortURL": "string",
                        "bookmarks": {
                          "bookmark1": {
                            "startTime": 0,
                            "endTime": 0,
                            "tag": "string",
                            "comment": "string",
                            "thumbnailURL": "string",
                            "shortURL": "string"
                          },
                          "bookmark2": {
                            "startTime": 0,
                            "endTime": 0,
                            "tag": "string",
                            "comment": "string",
                            "thumbnailURL": "string",
                            "shortURL": "string"
                          }
                        },
                        "exports": {
                          "export1": {
                            "status": "string",
                            "videoURL": "string",
                            "thumbnailURL": "string",
                            "error": "string"
                          }
                        }
                      },
                      "collection2": {
                        "name": "string",
                        "isPublic": true,
                        "eventKey": "string",
                        "mediaFileKey": "string",
                        "userID": "string",
                        "externalSystemID": "string",
                        "shortURL": "string",
                        "bookmarks": {
                          "bookmark3": {
                            "startTime": 0,
                            "endTime": 0,
                            "tag": "string",
                            "comment": "string",
                            "thumbnailURL": "string",
                            "shortURL": "string"
                          }
                        },
                        "exports": {}
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found"
          }
        }
      }
    },
    "/public/bookmark-collections/media-files/{mediaFileKey}": {
      "parameters": [
        {
          "schema": {
            "type": "string"
          },
          "name": "mediaFileKey",
          "in": "path",
          "required": true,
          "description": "The media file key"
        }
      ],
      "get": {
        "summary": "Bookmark Collections of Media File",
        "tags": ["Bookmark management"],
        "operationId": "get-bookmark-collections-of-media-file",
        "description": "Returns the Bookmark Collections attached to the Event, on a given MediaFile.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "bookmarkCollections": {
                      "type": "object",
                      "additionalProperties": {
                        "$ref": "#/components/schemas/BookmarkCollection"
                      }
                    }
                  },
                  "required": ["bookmarkCollections"],
                  "example": {
                    "bookmarkCollections": {
                      "collection1": {
                        "name": "string",
                        "isPublic": true,
                        "eventKey": "string",
                        "mediaFileKey": "string",
                        "userID": "string",
                        "externalSystemID": "string",
                        "shortURL": "string",
                        "bookmarks": {
                          "bookmark1": {
                            "startTime": 0,
                            "endTime": 0,
                            "tag": "string",
                            "comment": "string",
                            "thumbnailURL": "string",
                            "shortURL": "string"
                          },
                          "bookmark2": {
                            "startTime": 0,
                            "endTime": 0,
                            "tag": "string",
                            "comment": "string",
                            "thumbnailURL": "string",
                            "shortURL": "string"
                          }
                        },
                        "exports": {
                          "export1": {
                            "status": "string",
                            "videoURL": "string",
                            "thumbnailURL": "string",
                            "error": "string"
                          }
                        }
                      },
                      "collection2": {
                        "name": "string",
                        "isPublic": true,
                        "eventKey": "string",
                        "mediaFileKey": "string",
                        "userID": "string",
                        "externalSystemID": "string",
                        "shortURL": "string",
                        "bookmarks": {
                          "bookmark3": {
                            "startTime": 0,
                            "endTime": 0,
                            "tag": "string",
                            "comment": "string",
                            "thumbnailURL": "string",
                            "shortURL": "string"
                          }
                        },
                        "exports": {}
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found"
          }
        }
      },
      "post": {
        "summary": "Create Bookmark Collection for Media File",
        "tags": ["Bookmark management"],
        "operationId": "create-bookmark-collection-for-media-file",
        "description": "Creates a Bookmark Collection attached to the Event, on a specific Media File.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BookmarkCollectionCreationRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "bookmarkCollectionKey": {
                      "type": "string",
                      "description": "The key of the newly created Bookmark Collection"
                    }
                  },
                  "required": ["bookmarkCollectionKey"]
                }
              }
            }
          },
          "400": {
            "description": "Bad Request"
          },
          "404": {
            "description": "Not Found"
          }
        }
      }
    },
    "/public/bookmark-collections/media-files/{mediaFileKey}/{userID}": {
      "parameters": [
        {
          "schema": {
            "type": "string"
          },
          "name": "mediaFileKey",
          "in": "path",
          "required": true,
          "description": "The media file key"
        },
        {
          "schema": {
            "type": "string"
          },
          "name": "userID",
          "in": "path",
          "required": true,
          "description": "User ID to filter collections by owner"
        }
      ],
      "get": {
        "summary": "Bookmark Collections of Media File by User",
        "tags": ["Bookmark management"],
        "operationId": "get-bookmark-collections-of-media-file-by-user",
        "description": "Returns the Bookmark Collections attached to the Event, and the given MediaFile, that are owned by the specified user.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "bookmarkCollections": {
                      "type": "object",
                      "additionalProperties": {
                        "$ref": "#/components/schemas/BookmarkCollection"
                      }
                    }
                  },
                  "required": ["bookmarkCollections"],
                  "example": {
                    "bookmarkCollections": {
                      "collection1": {
                        "name": "string",
                        "isPublic": true,
                        "eventKey": "string",
                        "mediaFileKey": "string",
                        "userID": "string",
                        "externalSystemID": "string",
                        "shortURL": "string",
                        "bookmarks": {
                          "bookmark1": {
                            "startTime": 0,
                            "endTime": 0,
                            "tag": "string",
                            "comment": "string",
                            "thumbnailURL": "string",
                            "shortURL": "string"
                          },
                          "bookmark2": {
                            "startTime": 0,
                            "endTime": 0,
                            "tag": "string",
                            "comment": "string",
                            "thumbnailURL": "string",
                            "shortURL": "string"
                          }
                        },
                        "exports": {
                          "export1": {
                            "status": "string",
                            "videoURL": "string",
                            "thumbnailURL": "string",
                            "error": "string"
                          }
                        }
                      },
                      "collection2": {
                        "name": "string",
                        "isPublic": true,
                        "eventKey": "string",
                        "mediaFileKey": "string",
                        "userID": "string",
                        "externalSystemID": "string",
                        "shortURL": "string",
                        "bookmarks": {
                          "bookmark3": {
                            "startTime": 0,
                            "endTime": 0,
                            "tag": "string",
                            "comment": "string",
                            "thumbnailURL": "string",
                            "shortURL": "string"
                          }
                        },
                        "exports": {}
                      }
                    }
                  }
                }
              }
            }
          },
          "404": {
            "description": "Not Found"
          }
        }
      }
    },
    "/public/bookmark-collections/{bookmarkCollectionKey}": {
      "parameters": [
        {
          "schema": {
            "type": "string"
          },
          "name": "bookmarkCollectionKey",
          "in": "path",
          "required": true,
          "description": "The bookmark collection key"
        }
      ],
      "get": {
        "summary": "Bookmark Collection",
        "tags": ["Bookmark management"],
        "operationId": "get-bookmark-collection",
        "description": "Returns a Bookmark Collection by key.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/BookmarkCollection"
                }
              }
            }
          },
          "404": {
            "description": "Not Found"
          }
        }
      },
      "put": {
        "summary": "Update Bookmark Collection",
        "tags": ["Bookmark management"],
        "operationId": "update-bookmark-collection",
        "description": "Updates a Bookmark Collection. Only fields present in the body are updated.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BookmarkCollectionCreationRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not Found"
          }
        }
      },
      "delete": {
        "summary": "Delete Bookmark Collection",
        "tags": ["Bookmark management"],
        "operationId": "delete-bookmark-collection",
        "description": "Deletes a Bookmark Collection.",
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not Found"
          }
        }
      }
    },
    "/public/bookmark-collections/{bookmarkCollectionKey}/shortURL": {
      "parameters": [
        {
          "schema": {
            "type": "string"
          },
          "name": "bookmarkCollectionKey",
          "in": "path",
          "required": true,
          "description": "The bookmark collection key"
        }
      ],
      "get": {
        "summary": "Bookmark Collection Short URL",
        "tags": ["Bookmark management"],
        "operationId": "get-bookmark-collection-short-url",
        "description": "Returns (or creates) a short URL for the Bookmark Collection.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "shortURL": {
                      "type": "string",
                      "description": "Short URL for the collection"
                    }
                  },
                  "required": ["shortURL"]
                }
              }
            }
          },
          "404": {
            "description": "Not Found"
          }
        }
      }
    },
    "/public/bookmark-collections/{bookmarkCollectionKey}/export": {
      "parameters": [
        {
          "schema": {
            "type": "string"
          },
          "name": "bookmarkCollectionKey",
          "in": "path",
          "required": true,
          "description": "The bookmark collection key"
        }
      ],
      "post": {
        "summary": "Export Bookmark Collection by Tag",
        "tags": ["Bookmark management"],
        "operationId": "export-bookmark-collection-by-tag",
        "description": "Creates a video export for all bookmarks in the collection with a given tag.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BookmarkExportByTagRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "exportKey": {
                      "type": "string",
                      "description": "The export key"
                    }
                  },
                  "required": ["exportKey"]
                }
              }
            }
          },
          "400": {
            "description": "Bad Request"
          },
          "404": {
            "description": "Not Found"
          },
          "422": {
            "description": "Unprocessable Entity"
          }
        }
      }
    },
    "/public/bookmark-collections/{bookmarkCollectionKey}/export/{exportKey}": {
      "parameters": [
        {
          "schema": {
            "type": "string"
          },
          "name": "bookmarkCollectionKey",
          "in": "path",
          "required": true,
          "description": "The bookmark collection key"
        },
        {
          "schema": {
            "type": "string"
          },
          "name": "exportKey",
          "in": "path",
          "required": true,
          "description": "The export key"
        }
      ],
      "delete": {
        "summary": "Delete Bookmark Collection Export",
        "tags": ["Bookmark management"],
        "operationId": "delete-bookmark-collection-export",
        "description": "Deletes a previously created Bookmark Collection export.",
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not Found"
          }
        }
      }
    },
    "/public/bookmark-collections/{bookmarkCollectionKey}/bookmarks/{bookmarkKey}/shortURL": {
      "parameters": [
        {
          "schema": {
            "type": "string"
          },
          "name": "bookmarkCollectionKey",
          "in": "path",
          "required": true,
          "description": "The bookmark collection key"
        },
        {
          "schema": {
            "type": "string"
          },
          "name": "bookmarkKey",
          "in": "path",
          "required": true,
          "description": "The bookmark key"
        }
      ],
      "get": {
        "summary": "Bookmark Short URL",
        "tags": ["Bookmark management"],
        "operationId": "get-bookmark-short-url",
        "description": "Returns (or creates) a short URL for a specific bookmark in a collection.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "shortURL": {
                      "type": "string",
                      "description": "Short URL for the bookmark"
                    }
                  },
                  "required": ["shortURL"]
                }
              }
            }
          },
          "404": {
            "description": "Not Found"
          }
        }
      }
    },
    "/public/bookmark-collections/{bookmarkCollectionKey}/bookmarks": {
      "parameters": [
        {
          "schema": {
            "type": "string"
          },
          "name": "bookmarkCollectionKey",
          "in": "path",
          "required": true,
          "description": "The bookmark collection key"
        }
      ],
      "post": {
        "summary": "Create Bookmark",
        "tags": ["Bookmark management"],
        "operationId": "create-bookmark",
        "description": "Creates a Bookmark in the given collection.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BookmarkCreationRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "bookmarkKey": {
                      "type": "string",
                      "description": "The newly created bookmark key"
                    }
                  },
                  "required": ["bookmarkKey"]
                }
              }
            }
          },
          "400": {
            "description": "Bad Request"
          },
          "404": {
            "description": "Not Found"
          }
        }
      }
    },
    "/public/bookmark-collections/{bookmarkCollectionKey}/bookmarks/{bookmarkKey}": {
      "parameters": [
        {
          "schema": {
            "type": "string"
          },
          "name": "bookmarkCollectionKey",
          "in": "path",
          "required": true,
          "description": "The bookmark collection key"
        },
        {
          "schema": {
            "type": "string"
          },
          "name": "bookmarkKey",
          "in": "path",
          "required": true,
          "description": "The bookmark key"
        }
      ],
      "put": {
        "summary": "Update Bookmark",
        "tags": ["Bookmark management"],
        "operationId": "update-bookmark",
        "description": "Updates a Bookmark. Only fields present in the body are updated. Sending an empty `thumbnailBase64` clears the thumbnail.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/BookmarkUpdateRequest"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not Found"
          }
        }
      },
      "delete": {
        "summary": "Delete Bookmark",
        "tags": ["Bookmark management"],
        "operationId": "delete-bookmark",
        "description": "Deletes a Bookmark from the collection.",
        "responses": {
          "200": {
            "description": "OK"
          },
          "404": {
            "description": "Not Found"
          }
        }
      }
    },
    "/public/companies/{companyKeyOrSlug}/reels": {
      "parameters": [
        {
          "schema": {
            "type": "string"
          },
          "name": "companyKeyOrSlug",
          "in": "path",
          "required": true,
          "description": "The company/organization's key or slug"
        }
      ],
      "get": {
        "summary": "Reels of a Company/Organization",
        "tags": ["Reel management"],
        "operationId": "get-company-reels",
        "description": "Returns all the Reels owned by the given Company/organization.\n\nEach entry in the response is a trimmed-down representation of the Reel. For the full Reel data, including its playlist, a separate request should be made on the single Reel endpoint with the `reelKey` retrieved from this list.\n\nThe `eventKey` query parameter may be used to restrict the result to Reels attached to a specific Event.",
        "parameters": [
          {
            "schema": {
              "type": "string"
            },
            "in": "query",
            "name": "eventKey",
            "description": "When specified, only Reels attached to this Event are returned.",
            "required": false
          }
        ],
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "reels": {
                      "type": "array",
                      "description": "The list of Reels",
                      "items": {
                        "$ref": "#/components/schemas/ReelShort"
                      }
                    }
                  },
                  "required": ["reels"]
                }
              }
            }
          },
          "403": {
            "description": "Forbidden"
          },
          "404": {
            "description": "Not Found"
          }
        }
      },
      "post": {
        "summary": "Create a Reel",
        "tags": ["Reel management"],
        "operationId": "create-company-reel",
        "description": "Creates a Reel owned by the given Company/organization.\n\nA Reel is an ordered sequence of video clip excerpts (the `playlist`) that can be played back as a single highlights video. Each playlist element points to a video clip and specifies the portion of the clip to play, along with an optional text overlay.\n\nUpon successful creation, the `reelKey` of the newly created Reel is returned. The Reel may thereafter be referred to by that `reelKey`.\n\nOnly the `name` field is mandatory in the body data. If provided, `playlist` must be an ordered array; the playback order matches the array order.\n\nThe `thumbnail` field, if provided, must be a base64-encoded PNG or JPEG image. The image is uploaded to the Sporfie system and its resulting URL becomes the Reel's `thumbnailURL`. Alternatively, `thumbnailURL` may be set directly to point to an already-hosted image.\n\nThe `eventKey`, when provided, attaches the Reel to a specific Event.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReelCreate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "reelKey": {
                      "type": "string",
                      "description": "The key of the newly created Reel"
                    }
                  },
                  "required": ["reelKey"]
                }
              }
            }
          },
          "403": {
            "description": "Forbidden"
          },
          "404": {
            "description": "Not Found"
          }
        }
      }
    },
    "/public/companies/{companyKeyOrSlug}/reels/{reelKey}": {
      "parameters": [
        {
          "schema": {
            "type": "string"
          },
          "name": "companyKeyOrSlug",
          "in": "path",
          "required": true,
          "description": "The company/organization's key or slug"
        },
        {
          "schema": {
            "type": "string"
          },
          "name": "reelKey",
          "in": "path",
          "required": true,
          "description": "The Reel key"
        }
      ],
      "get": {
        "summary": "Reel",
        "tags": ["Reel management"],
        "operationId": "get-company-reel",
        "description": "Returns the full data for a Reel owned by the given Company/organization, including its playlist and, when available, its conversion state.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "$ref": "#/components/schemas/Reel"
                }
              }
            }
          },
          "403": {
            "description": "Forbidden"
          },
          "404": {
            "description": "Not Found"
          }
        }
      },
      "put": {
        "summary": "Update a Reel",
        "tags": ["Reel management"],
        "operationId": "update-company-reel",
        "description": "Modifies an existing Reel.\n\nNo field is mandatory in the body data. Only fields present in the body will be updated, other fields will be left unmodified. The `playlist` field is considered as an atomic value: sending a `playlist` replaces the existing one entirely.\n\nThe `thumbnail` field, if provided, must be a base64-encoded PNG or JPEG image. The image is uploaded to the Sporfie system and its resulting URL becomes the Reel's `thumbnailURL`.\n\nThe `eventKey` of a Reel may not be modified through this endpoint.",
        "requestBody": {
          "required": true,
          "content": {
            "application/json": {
              "schema": {
                "$ref": "#/components/schemas/ReelCreate"
              }
            }
          }
        },
        "responses": {
          "200": {
            "description": "OK"
          },
          "403": {
            "description": "Forbidden"
          },
          "404": {
            "description": "Not Found"
          }
        }
      },
      "delete": {
        "summary": "Delete a Reel",
        "tags": ["Reel management"],
        "operationId": "delete-company-reel",
        "description": "Deletes a Reel.\n\nIf the Reel has previously been converted to a video file, the generated video file is also removed.",
        "responses": {
          "200": {
            "description": "OK"
          },
          "403": {
            "description": "Forbidden"
          },
          "404": {
            "description": "Not Found"
          }
        }
      }
    },
    "/public/companies/{companyKeyOrSlug}/reels/{reelKey}/convertToVideoFile": {
      "parameters": [
        {
          "schema": {
            "type": "string"
          },
          "name": "companyKeyOrSlug",
          "in": "path",
          "required": true,
          "description": "The company/organization's key or slug"
        },
        {
          "schema": {
            "type": "string"
          },
          "name": "reelKey",
          "in": "path",
          "required": true,
          "description": "The Reel key"
        }
      ],
      "post": {
        "summary": "Convert a Reel to a video file",
        "tags": ["Reel management"],
        "operationId": "convert-company-reel-to-video-file",
        "description": "Triggers the generation of a single, self-contained MP4 video file from the Reel's playlist.\n\nThe conversion is asynchronous: a positive response only indicates that the request has been accepted and that the generation is under way. The progress and result of the conversion can be observed through the `conversion` field on the Reel (see the Reel data endpoint).\n\nWhen the conversion completes successfully, the `conversion.videoURL` field is populated with the URL of the generated video.\n\n### Behavior\n\n- If the Reel has an empty playlist, a `422` is returned.\n- If a conversion is already in progress for that Reel, a `409` is returned.\n- If the Reel has already been converted since its last modification (i.e. the existing conversion is up-to-date with the Reel's current state), a `202` is returned and no new conversion is triggered.",
        "responses": {
          "200": {
            "description": "OK — the conversion has been started"
          },
          "202": {
            "description": "Accepted — an up-to-date conversion already exists for this Reel, no new conversion was started"
          },
          "403": {
            "description": "Forbidden"
          },
          "404": {
            "description": "Not Found"
          },
          "409": {
            "description": "Conflict — a conversion is already in progress for this Reel"
          },
          "422": {
            "description": "Unprocessable Entity — the Reel has no playlist elements to convert"
          }
        }
      }
    },
    "/public/scopes/{scopeKey}/companies": {
      "parameters": [
        {
          "schema": {
            "type": "string"
          },
          "name": "scopeKey",
          "in": "path",
          "required": true,
          "description": "The Scope key"
        }
      ],
      "get": {
        "summary": "Companies of a Scope",
        "tags": ["Scope data"],
        "operationId": "get-scope-companies",
        "description": "Returns the Companies/Organizations that belong to the given Scope.\n\nA Scope groups a parent Company with its child Companies under a shared branding and configuration.\n\nThe `parentCompanyKey` field is the key of the Scope's parent Company. The `companies` field is the list of Companies in the Scope; each entry holds a trimmed-down representation of the Company.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "object",
                  "properties": {
                    "parentCompanyKey": {
                      "type": "string",
                      "description": "The key of the Scope's parent Company"
                    },
                    "companies": {
                      "type": "array",
                      "description": "The Companies belonging to this Scope",
                      "items": {
                        "$ref": "#/components/schemas/ScopedCompany"
                      }
                    }
                  },
                  "required": ["parentCompanyKey", "companies"]
                }
              }
            }
          },
          "403": {
            "description": "Forbidden"
          },
          "404": {
            "description": "Not Found"
          }
        }
      }
    },
    "/public/sports": {
      "get": {
        "summary": "Sports",
        "tags": ["Sport data"],
        "operationId": "get-sports",
        "description": "Returns the list of sport codes supported by the Sporfie system, sorted alphabetically.\n\nEach entry is the sport code (e.g. `tennis`, `baseball`) that may be used as the `sport` value on a Place or Event.",
        "responses": {
          "200": {
            "description": "OK",
            "content": {
              "application/json": {
                "schema": {
                  "type": "array",
                  "description": "The list of supported sport codes",
                  "items": {
                    "type": "string"
                  }
                }
              }
            }
          }
        }
      }
    }
  },
  "components": {
    "securitySchemes": {
      "bearerAuth": {
        "type": "http",
        "scheme": "bearer",
        "bearerFormat": "JWT",
        "description": "Your Sporfie API token, sent as `Authorization: Bearer {token}`.\n\nCreate one at https://sporfie.com/settings/developer. The token is shown once, at creation.\n\nThe token must stay on your server. Never ship it in a web app, mobile app or any client-side code."
      }
    },
    "parameters": {},
    "schemas": {
      "SportKey": {
        "type": "string",
        "title": "SportKey",
        "description": "A sport identifier key",
        "enum": [
          "ballhockey",
          "baseball",
          "basketball",
          "beachvolleyball",
          "billiard",
          "bowling",
          "cheer",
          "cricket",
          "dekhockey",
          "football",
          "frontenis",
          "futsal",
          "golf",
          "handball",
          "hockey",
          "lacrosse",
          "other",
          "padel",
          "pickleball",
          "pongbeyond",
          "rollerderby",
          "rugby",
          "soccer",
          "softball",
          "swimming",
          "tennis",
          "unihockey",
          "volleyball",
          "waterpolo",
          "wrestling"
        ]
      },
      "Click": {
        "type": "object",
        "description": "The trigger for recording a moment in time.\n\nAs a convenience, a `score` object may be passed with the click. It will be associated with the Moment created by the click.\nThe `score` object may contain any score information that is relevant for the sport of the event. It must contain a `timeStamp` field.\n\n**The `timeStamp` and `key` fields are reserved field names in the score object**.\n",
        "x-examples": {
          "Example": {
            "timeStamp": 1622794039630,
            "startTime": 1622794030630,
            "endTime": 1622794042630
          }
        },
        "title": "Click",
        "properties": {
          "timeStamp": {
            "type": "integer",
            "description": "Absolute time of the click (UTC, unix epoch in milliseconds)"
          },
          "startTime": {
            "type": "integer",
            "description": "Absolute start time of the recording window (UTC, unix epoch in milliseconds). If `startTime` is present, `endTime` must also be."
          },
          "endTime": {
            "type": "integer",
            "description": "Absolute end time of the recording window (UTC, unix epoch in milliseconds). If `endTime` is present, `startTime` must also be."
          },
          "score": {
            "type": "object",
            "description": "The score information associated with this moment in time. Must contain the `timeStamp` field but may otherwise contain any other sport-specific score information.\n**The `timeStamp` and `key` fields are reserved field names in the score object**. Keys may not contain the following characters `. $ # [ ] /`",
            "properties": {
              "timeStamp": {
                "type": "integer",
                "description": "Absolute time of the score information (UTC, unix epoch in milliseconds)"
              }
            },
            "required": ["timeStamp"]
          },
          "overlays": {
            "type": "array",
            "description": "Overlays to apply on this moment's videos",
            "items": {
              "$ref": "#/components/schemas/Overlay"
            }
          },
          "players": {
            "type": "array",
            "description": "Player information",
            "items": {
              "$ref": "#/components/schemas/Player"
            }
          },
          "metadata": {
            "type": "object",
            "description": "A dictionary of custom fields. Its JSON string representation (UTF-8) may not exceed 500 bytes. Keys may not contain the following characters `. $ # [ ] /`"
          }
        },
        "required": ["timeStamp"],
        "writeOnly": true
      },
      "Player": {
        "type": "object",
        "description": "Player information",
        "properties": {
          "id": {
            "type": "string",
            "description": "The player unique identifier"
          },
          "name": {
            "type": "string",
            "description": "The player's name"
          }
        }
      },
      "Overlay": {
        "title": "Overlay",
        "type": "object",
        "description": "This structure describes an overlay to be added to a video clip.\n",
        "properties": {
          "imageSource": {
            "type": "string",
            "description": "URL to the image (PNG or JPEG) to embed. **Must** be present if `templateSource` is not."
          },
          "templateSource": {
            "type": "string",
            "description": "URL to the HTML file to use to render the overlay. **Must** be present if `imageSource` is not."
          },
          "values": {
            "type": "object",
            "description": "Provides the value for each placeholder found in the template"
          },
          "position": {
            "description": "The position of the overlay within the video.",
            "type": "object",
            "required": ["horizontal", "vertical"],
            "properties": {
              "horizontal": {
                "type": "string",
                "description": "One of `left`, `center`, `right`"
              },
              "vertical": {
                "type": "string",
                "description": "One of `top`, `center`, `bottom`"
              }
            }
          },
          "heightPercentOfHeight": {
            "type": "integer",
            "description": "The height of the overlay in percent of the video’s height (0-100). Mutually exclusive with `widthPercentOfWidth`. One of the two **must** be specified. If both are specified, `heightPercentOfHeight` takes precedence."
          },
          "widthPercentOfWidth": {
            "type": "integer",
            "description": "The width of the overlay in percent of the video’s width (0-100). Mutually exclusive with `heightPercentOfHeight`. One of the two **must** be specified. If both are specified, `widthPercentOfWidth` takes precedence."
          },
          "marginPercentOfHeight": {
            "type": "integer",
            "description": "The margin from the video’s corner to apply in percent of the video’s height (0-100). Mutually exclusive with `marginPercentOfWidth`, if both are specified, `marginPercentOfHeight` takes precedence."
          },
          "marginPercentOfWidth": {
            "type": "integer",
            "description": "The margin from the video’s corner to apply in percent of the video’s width (0-100). Mutually exclusive with `marginPercentOfHeight`, if both are specified, `marginPercentOfHeight` takes precedence."
          },
          "startTime": {
            "type": "integer",
            "description": "When to start displaying the overlay, in milliseconds, relative to the start of the video clip. If not specified, 0 is assumed."
          },
          "duration": {
            "type": "integer",
            "description": "How long to display the overlay in milliseconds. If not specified, the duration of the video is assumed."
          }
        },
        "required": ["position"]
      },
      "Bookmark": {
        "type": "object",
        "description": "A bookmarked clip within a Bookmark Collection.",
        "properties": {
          "startTime": {
            "type": "integer",
            "description": "Start time of the clip (UTC, unix epoch in milliseconds)"
          },
          "endTime": {
            "type": "integer",
            "nullable": true,
            "description": "End time of the clip (UTC, unix epoch in milliseconds)"
          },
          "tag": {
            "type": "string",
            "nullable": true,
            "description": "Optional tag label"
          },
          "comment": {
            "type": "string",
            "nullable": true,
            "description": "Optional free-form comment"
          },
          "thumbnailURL": {
            "type": "string",
            "nullable": true,
            "description": "Public URL of the bookmark thumbnail image"
          },
          "shortURL": {
            "type": "string",
            "nullable": true,
            "description": "Short URL for sharing this bookmark"
          }
        }
      },
      "BookmarkExport": {
        "type": "object",
        "description": "Bookmark export metadata (structure may vary by export type)",
        "properties": {
          "status": {
            "type": "string",
            "description": "The status of the export"
          },
          "videoURL": {
            "type": "string",
            "description": "Public URL of the video"
          },
          "thumbnailURL": {
            "type": "string",
            "description": "Public URL of the thumbnail"
          },
          "error": {
            "type": "string",
            "description": "Error message if the export failed"
          },
          "videoSize": {
            "type": "integer",
            "description": "Size of the video in bytes"
          },
          "videoDuration": {
            "type": "number",
            "description": "Duration of the video in seconds (floating point number)"
          }
        }
      },
      "BookmarkCollection": {
        "type": "object",
        "description": "A collection of bookmarks for an Event (optionally scoped to a Media File).",
        "properties": {
          "name": {
            "type": "string",
            "description": "Display name of the collection"
          },
          "isPublic": {
            "type": "boolean",
            "description": "Whether the collection is visible to other users"
          },
          "eventKey": {
            "type": "string",
            "description": "Associated Event key"
          },
          "mediaFileKey": {
            "type": "string",
            "nullable": true,
            "description": "If present, the collection is scoped to this Media File"
          },
          "userID": {
            "type": "string",
            "nullable": true,
            "description": "Owner user ID (for user-owned collections)"
          },
          "externalSystemID": {
            "type": "string",
            "nullable": true,
            "description": "Owner external system ID (for system-owned collections)"
          },
          "shortURL": {
            "type": "string",
            "nullable": true,
            "description": "Short URL for sharing this collection"
          },
          "bookmarks": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/Bookmark"
            },
            "description": "Bookmarks keyed by bookmark key"
          },
          "exports": {
            "type": "object",
            "additionalProperties": {
              "$ref": "#/components/schemas/BookmarkExport"
            },
            "description": "Exports keyed by export key"
          }
        },
        "example": {
          "name": "string",
          "isPublic": true,
          "eventKey": "string",
          "mediaFileKey": "string",
          "userID": "string",
          "externalSystemID": "string",
          "shortURL": "string",
          "bookmarks": {
            "bookmark1": {
              "startTime": 0,
              "endTime": 0,
              "tag": "string",
              "comment": "string",
              "thumbnailURL": "string",
              "shortURL": "string"
            },
            "bookmark2": {
              "startTime": 0,
              "endTime": 0,
              "tag": "string",
              "comment": "string",
              "thumbnailURL": "string",
              "shortURL": "string"
            }
          },
          "exports": {
            "export1": {
              "status": "string",
              "videoURL": "string",
              "thumbnailURL": "string",
              "error": "string"
            }
          }
        }
      },
      "BookmarkCollectionCreationRequest": {
        "type": "object",
        "description": "Request body to create or update a Bookmark Collection.",
        "properties": {
          "name": {
            "type": "string",
            "description": "Collection name"
          },
          "isPublic": {
            "type": "boolean",
            "description": "Whether the collection is public"
          }
        },
        "required": ["name", "isPublic"]
      },
      "BookmarkCreationRequest": {
        "type": "object",
        "description": "Request body to create a Bookmark.",
        "properties": {
          "startTime": {
            "type": "integer",
            "description": "Absolute start time (UTC, unix epoch in milliseconds)"
          },
          "endTime": {
            "type": "integer",
            "description": "Absolute end time (UTC, unix epoch in milliseconds)"
          },
          "tag": {
            "type": "string",
            "description": "Optional tag label"
          },
          "comment": {
            "type": "string",
            "description": "Optional free-form comment"
          },
          "thumbnailBase64": {
            "type": "string",
            "description": "Base64-encoded PNG or JPEG image to be saved as the bookmark thumbnail"
          }
        },
        "required": ["startTime"]
      },
      "BookmarkUpdateRequest": {
        "type": "object",
        "description": "Request body to update a Bookmark. Only provided fields are updated. Send an empty string for `thumbnailBase64` to clear the thumbnail.",
        "properties": {
          "startTime": {
            "type": "integer",
            "description": "Absolute start time (UTC, ms)"
          },
          "endTime": {
            "type": "integer",
            "description": "Absolute end time (UTC, ms)"
          },
          "tag": {
            "type": "string",
            "description": "Optional tag label"
          },
          "comment": {
            "type": "string",
            "description": "Optional free-form comment"
          },
          "thumbnailBase64": {
            "type": "string",
            "description": "Base64-encoded PNG or JPEG image; send empty string to remove existing thumbnail"
          }
        }
      },
      "BookmarkExportByTagRequest": {
        "type": "object",
        "description": "Request body to export all bookmarks of a collection that share a given tag.",
        "properties": {
          "name": {
            "type": "string",
            "description": "Export display name"
          },
          "tag": {
            "type": "string",
            "description": "Tag to filter bookmarks"
          },
          "mediaFileKey": {
            "type": "string",
            "description": "Media File key to use for the export"
          }
        },
        "required": ["name", "tag", "mediaFileKey"]
      },
      "Reel": {
        "description": "A Reel: an ordered sequence of video clip excerpts played back as a single highlights video.",
        "type": "object",
        "properties": {
          "companyKey": {
            "type": "string",
            "description": "The identifier of the Company/organization that owns this Reel"
          },
          "reelKey": {
            "type": "string",
            "description": "The unique identifier of the Reel"
          },
          "eventKey": {
            "type": "string",
            "description": "The identifier of the Event this Reel is attached to, if any"
          },
          "name": {
            "type": "string",
            "description": "The Reel name"
          },
          "creationDate": {
            "type": "integer",
            "description": "The date & time of creation of the Reel (UTC, epoch in milliseconds)"
          },
          "lastModificationDate": {
            "type": "integer",
            "description": "The date & time of the last modification of the Reel (UTC, epoch in milliseconds)"
          },
          "shareURL": {
            "type": "string",
            "description": "A shareable link to the Reel"
          },
          "thumbnailURL": {
            "type": "string",
            "description": "The URL of the Reel thumbnail"
          },
          "playlist": {
            "type": "array",
            "description": "The ordered list of playlist elements composing the Reel. The playback order matches the array order.",
            "items": {
              "$ref": "#/components/schemas/ReelPlaylistElement"
            }
          },
          "conversion": {
            "$ref": "#/components/schemas/ReelConversion"
          }
        },
        "required": ["reelKey", "name", "creationDate", "lastModificationDate"]
      },
      "ReelShort": {
        "description": "A shorter version of a Reel, used when listing multiple Reels.",
        "type": "object",
        "properties": {
          "companyKey": {
            "type": "string",
            "description": "The identifier of the Company/organization that owns this Reel"
          },
          "reelKey": {
            "type": "string",
            "description": "The unique identifier of the Reel"
          },
          "eventKey": {
            "type": "string",
            "description": "The identifier of the Event this Reel is attached to, if any"
          },
          "name": {
            "type": "string",
            "description": "The Reel name"
          },
          "creationDate": {
            "type": "integer",
            "description": "The date & time of creation of the Reel (UTC, epoch in milliseconds)"
          },
          "lastModificationDate": {
            "type": "integer",
            "description": "The date & time of the last modification of the Reel (UTC, epoch in milliseconds)"
          },
          "shareURL": {
            "type": "string",
            "description": "A shareable link to the Reel"
          },
          "thumbnailURL": {
            "type": "string",
            "description": "The URL of the Reel thumbnail"
          },
          "conversionStatus": {
            "type": "string",
            "description": "The status of the latest conversion of this Reel to a video file, if any. One of `RUNNING`, `COMPLETED`, `FAILED`.",
            "enum": ["RUNNING", "COMPLETED", "FAILED"]
          },
          "conversionVideoURL": {
            "type": "string",
            "description": "The URL of the MP4 video generated by the latest conversion of this Reel, if any. Only present once a conversion has completed successfully."
          }
        },
        "required": ["reelKey", "name", "creationDate", "lastModificationDate"]
      },
      "ReelCreate": {
        "title": "ReelCreate",
        "type": "object",
        "description": "A Reel payload used when creating or updating a Reel.",
        "properties": {
          "eventKey": {
            "type": "string",
            "description": "The identifier of the Event to attach this Reel to. Only honored at creation time."
          },
          "name": {
            "type": "string",
            "description": "The Reel name. May not be empty."
          },
          "thumbnail": {
            "type": "string",
            "description": "A base64-encoded PNG or JPEG image to be uploaded and used as the Reel thumbnail. When provided, the resulting URL is stored as the Reel's `thumbnailURL`."
          },
          "thumbnailURL": {
            "type": "string",
            "description": "A URL pointing to an already-hosted image to use as the Reel thumbnail. Ignored if `thumbnail` is also provided."
          },
          "playlist": {
            "type": "array",
            "description": "The ordered list of playlist elements composing the Reel. The playback order matches the array order.",
            "items": {
              "$ref": "#/components/schemas/ReelPlaylistElementUpdate"
            }
          }
        },
        "required": ["name"]
      },
      "ReelPlaylistElement": {
        "description": "A single element in a Reel's playlist: a video clip excerpt with an optional text overlay.",
        "type": "object",
        "properties": {
          "videoClipKey": {
            "type": "string",
            "description": "The key of the video clip used as the source for this playlist element"
          },
          "startTime": {
            "type": "integer",
            "description": "The start time of the excerpt within the source video clip, in milliseconds"
          },
          "endTime": {
            "type": "integer",
            "description": "The end time of the excerpt within the source video clip, in milliseconds"
          },
          "textOverlay": {
            "$ref": "#/components/schemas/ReelTextOverlay"
          },
          "thumbnailURL": {
            "type": "string",
            "description": "The thumbnail URL of the source video clip"
          },
          "thumbnailSizes": {
            "type": "string",
            "description": "The thumbnail sizes descriptor of the source video clip"
          },
          "videoURL": {
            "type": "string",
            "description": "The video URL of the source video clip"
          },
          "downloadURL": {
            "type": "string",
            "description": "A download URL of the source video clip"
          },
          "event": {
            "type": "object",
            "description": "Essential information about the Event the source video clip belongs to",
            "properties": {
              "key": {
                "type": "string",
                "description": "The event key"
              },
              "name": {
                "type": "string",
                "description": "The event name"
              },
              "locationName": {
                "type": "string",
                "description": "The name of the location at which the event takes place"
              }
            }
          }
        }
      },
      "ReelPlaylistElementUpdate": {
        "description": "A playlist element payload used when creating or updating a Reel.",
        "type": "object",
        "properties": {
          "videoClipKey": {
            "type": "string",
            "description": "The key of the video clip used as the source for this playlist element"
          },
          "startTime": {
            "type": "integer",
            "description": "The start time of the excerpt within the source video clip, in milliseconds"
          },
          "endTime": {
            "type": "integer",
            "description": "The end time of the excerpt within the source video clip, in milliseconds"
          },
          "textOverlay": {
            "$ref": "#/components/schemas/ReelTextOverlay"
          }
        },
        "required": ["videoClipKey"]
      },
      "ReelTextOverlay": {
        "description": "A text overlay applied on a playlist element.",
        "type": "object",
        "properties": {
          "useComment": {
            "type": "boolean",
            "description": "When `true`, the comment associated with the source video clip is used as the overlay text, and the `text` field is ignored."
          },
          "text": {
            "type": "string",
            "description": "The literal text to display as the overlay. Ignored when `useComment` is `true`."
          }
        }
      },
      "ReelConversion": {
        "description": "The state of a Reel's conversion to a single MP4 video file.",
        "type": "object",
        "properties": {
          "status": {
            "type": "string",
            "description": "The current status of the conversion",
            "enum": ["RUNNING", "COMPLETED", "FAILED"]
          },
          "sourceModificationDate": {
            "type": "integer",
            "description": "The `lastModificationDate` of the Reel at the time the conversion was started (UTC, epoch in milliseconds). Used to determine whether the conversion is still up-to-date with the current state of the Reel."
          },
          "requestTime": {
            "type": "integer",
            "description": "The date & time at which the conversion was requested (UTC, epoch in milliseconds)"
          },
          "completionTime": {
            "type": "integer",
            "description": "The date & time at which the conversion completed (UTC, epoch in milliseconds). Only present when the conversion has terminated."
          },
          "videoURL": {
            "type": "string",
            "description": "The URL of the generated MP4 video. Only present once the conversion has completed successfully."
          }
        }
      },
      "Event": {
        "description": "A Sporfie Event.",
        "type": "object",
        "x-examples": {
          "example-1": {
            "value": {
              "key": "string",
              "name": "string",
              "creationDate": 0,
              "scheduledStartTime": 0,
              "announcedTime": 0,
              "startTime": 0,
              "endTime": 0,
              "description": "string",
              "thumbnailURL": "string",
              "homeTeam": "string",
              "awayTeam": "string",
              "shortInviteUrl": "string",
              "score": {},
              "scoreSupported": true,
              "highlightsURL": "string",
              "highlightsShareURL": "string",
              "location": {
                "name": "string",
                "geoLoc": {
                  "lat": 0,
                  "lng": 0
                }
              },
              "moments": [
                {
                  "key": "string",
                  "momentStatus": "string",
                  "momentStartTime": 0,
                  "videoClips": [
                    {
                      "key": "string",
                      "rank": 0,
                      "thumbnailURL": "string",
                      "videoURL": "string",
                      "downloadURL": "string",
                      "shortUrl": "string",
                      "views": 0,
                      "orientation": "string",
                      "thumbnailSizes": "string",
                      "startTime": 0,
                      "endTime": 0
                    }
                  ],
                  "players": [
                    {
                      "id": "string",
                      "name": "string"
                    }
                  ],
                  "metadata": {}
                }
              ],
              "mediaFiles": [
                {
                  "startTime": 0,
                  "thumbnailURL": "string",
                  "videoURL": "string",
                  "downloadURL": "string",
                  "status": "m3u8_uploaded"
                }
              ],
              "hiddenDevices": {
                "string": true
              },
              "liveStreams": [
                {
                  "thumbnailURL": "string",
                  "liveURL": "string",
                  "deviceID": "string"
                }
              ]
            }
          }
        },
        "title": "",
        "properties": {
          "key": {
            "type": "string",
            "minLength": 1,
            "description": "The unique identifier of the event in the Sporfie system"
          },
          "externalEventID": {
            "type": "string",
            "minLength": 1,
            "description": "The event's external event identifier, if there is one"
          },
          "companyKey": {
            "type": "string",
            "minLength": 1,
            "description": "The identifier of the company/organization this event is associated with"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "description": "The event name"
          },
          "description": {
            "type": "string",
            "description": "The description of the event"
          },
          "notSearchable": {
            "description": "True when the event is excluded from public listing in the Sporfie system. Default value is `false`.",
            "type": "boolean"
          },
          "creationDate": {
            "type": "integer",
            "description": "The date & time of creation of the event (UTC, epoch in milliseconds)"
          },
          "placeKey": {
            "type": "string",
            "description": "The key of the Place on which the event is scheduled to run."
          },
          "scheduledStartTime": {
            "type": "integer",
            "description": "The date & time the event is scheduled to start (UTC, epoch in milliseconds)"
          },
          "scheduledEndTime": {
            "type": "integer",
            "description": "The date & time the event is scheduled to end (UTC, epoch in milliseconds)"
          },
          "announcedTime": {
            "type": "integer",
            "description": "The date & time the event is announced to start (UTC, epoch in milliseconds)"
          },
          "startTime": {
            "type": "integer",
            "description": "The date & time the event was started (UTC, epoch in milliseconds). Not available until the event is actually started"
          },
          "endTime": {
            "type": "integer",
            "description": "The date & time the event ended (UTC, epoch in milliseconds). Not available until the event is closed."
          },
          "thumbnailURL": {
            "type": "string",
            "minLength": 1,
            "description": "The event thumbnail"
          },
          "homeTeam": {
            "type": "string",
            "description": "The name of the team playing at home"
          },
          "awayTeam": {
            "type": "string",
            "description": "The name of the team playing away"
          },
          "shortInviteUrl": {
            "type": "string",
            "minLength": 1,
            "description": "The short invite URL"
          },
          "sport": {
            "$ref": "#/components/schemas/SportKey",
            "description": "The sport code for this event"
          },
          "pinCode": {
            "description": "The pin code controlling access to the event. A value of -1 or between 0000 and 9999. A value of -1 indicates no pin code. Default is -1.",
            "type": "number"
          },
          "cameraPinCode": {
            "description": "The pin code required to add a camera and edit the score. A value of -1 or between 0000 and 9999. A value of -1 indicates no pin code. Default is -1.",
            "type": "number"
          },
          "scoreSupported": {
            "type": "boolean",
            "description": "True if scoring is supported on this event"
          },
          "score": {
            "$ref": "#/components/schemas/Score"
          },
          "scoreStream": {
            "type": "array",
            "description": "The complete score history",
            "items": {
              "$ref": "#/components/schemas/Score"
            }
          },
          "highlightsURL": {
            "type": "string",
            "minLength": 1,
            "description": "The URL to the highlight reel video"
          },
          "highlightsShareURL": {
            "type": "string",
            "minLength": 1,
            "description": "A shareable link to the highlight reel video"
          },
          "location": {
            "$ref": "#/components/schemas/Location"
          },
          "moments": {
            "type": "array",
            "uniqueItems": true,
            "description": "The captured moments",
            "items": {
              "$ref": "#/components/schemas/Moment"
            }
          },
          "mediaFiles": {
            "type": "array",
            "description": "The stream recordings for this event (one per camera)",
            "uniqueItems": true,
            "items": {
              "$ref": "#/components/schemas/MediaFile"
            }
          },
          "hiddenDevices": {
            "type": "object",
            "description": "A string-to-boolean dictionary to hide or show the content of the devices that are contributing to this event. If a device is hidden, all the content it produces (live) or has produced (replay) is hidden from end-users. The key is the device ID, the value is `true` to hide the device or `false` to show it. If a device is not present in this dictionary, it is shown by default. Device IDs are listed in the liveStreams and mediaFiles arrays."
          },
          "liveStreams": {
            "type": "array",
            "description": "List of live streams currently available",
            "items": {
              "$ref": "#/components/schemas/LiveStream"
            }
          },
          "metadata": {
            "type": "object",
            "description": "A dictionary of custom fields provided by the external system at event creation"
          }
        },
        "required": [
          "key",
          "name",
          "creationDate",
          "startTime",
          "thumbnailURL",
          "shortInviteUrl",
          "sport",
          "pinCode",
          "cameraPinCode",
          "scoreSupported",
          "location",
          "moments",
          "mediaFiles"
        ]
      },
      "EventShort": {
        "description": "A shorter version of the Sporfie event used when listing multiple events.",
        "type": "object",
        "x-examples": {
          "example-1": {
            "key": "string",
            "externalEventID": "string",
            "name": "string",
            "creationDate": 0,
            "scheduledStartTime": 0,
            "announcedTime": 0,
            "startTime": 0,
            "endTime": 0,
            "description": "string",
            "thumbnailURL": "string",
            "metadata": {}
          }
        },
        "properties": {
          "key": {
            "type": "string",
            "minLength": 1,
            "description": "The Sporfie internal identifier of the event for that place at that time"
          },
          "externalEventID": {
            "type": "string",
            "minLength": 1,
            "description": "The event's external ID, if there is one"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "description": "The event name"
          },
          "creationDate": {
            "type": "integer",
            "description": "The date & time of creation of the event (UTC, epoch in milliseconds)"
          },
          "scheduledStartTime": {
            "type": "integer",
            "description": "The date & time the event is scheduled to start (UTC, epoch in milliseconds)"
          },
          "scheduledEndTime": {
            "type": "integer",
            "description": "The date & time the event is scheduled to end (UTC, epoch in milliseconds)"
          },
          "announcedTime": {
            "type": "integer",
            "description": "The date & time the event is announced to start (UTC, epoch in milliseconds)"
          },
          "startTime": {
            "type": "integer",
            "description": "The date & time the event was started (UTC, epoch in milliseconds). Not available until the event is actually started"
          },
          "endTime": {
            "type": "integer",
            "description": "The date & time the event ended (UTC, epoch in milliseconds). Not available until the event is closed."
          },
          "description": {
            "type": "string",
            "minLength": 1,
            "description": "The description of the event"
          },
          "thumbnailURL": {
            "type": "string",
            "minLength": 1,
            "description": "The event thumbnail"
          },
          "metadata": {
            "type": "object",
            "description": "A dictionary of custom fields provided by the external system at event creation"
          }
        },
        "required": ["key", "name", "creationDate", "thumbnailURL"]
      },
      "EventCreate": {
        "title": "EventCreate",
        "type": "object",
        "description": "A Sporfie event (used in the event creation API)",
        "properties": {
          "companyKey": {
            "type": "string",
            "description": "The identifier of the company/organization this event is associated with"
          },
          "name": {
            "type": "string",
            "description": "The event name. May not be empty."
          },
          "description": {
            "type": "string",
            "description": "The event description"
          },
          "notSearchable": {
            "description": "Set to true to exclude this event from public listing in the Sporfie system. Default value is `false`.",
            "type": "boolean"
          },
          "placeKey": {
            "type": "string",
            "description": "The key of the Place on which the event is scheduled to run."
          },
          "scheduledStartTime": {
            "type": "number",
            "description": "The date & time the event is scheduled to start (UTC, epoch in milliseconds)"
          },
          "scheduledEndTime": {
            "type": "number",
            "description": "The date & time the event is scheduled to end (UTC, epoch in milliseconds)"
          },
          "thumbnailURL": {
            "type": "string",
            "description": "A public URL pointing to the event's thumbnail"
          },
          "homeTeam": {
            "type": "string",
            "description": "The name of the team playing at home"
          },
          "awayTeam": {
            "type": "string",
            "description": "The name of the team playing away"
          },
          "sport": {
            "$ref": "#/components/schemas/SportKey",
            "description": "The sport code for this event"
          },
          "pinCode": {
            "type": "number",
            "description": "The pin code controlling access to the event. A value of -1 or between 0000 and 9999. A value of -1 indicates no pin code. Default is -1."
          },
          "cameraPinCode": {
            "type": "number",
            "description": "The pin code required to add a camera and edit the score. A value of -1 or between 0000 and 9999. A value of -1 indicates no pin code. Default is -1."
          },
          "location": {
            "$ref": "#/components/schemas/Location"
          },
          "metadata": {
            "type": "object",
            "description": "A dictionary of custom fields. Its JSON string representation (UTF-8) may not exceed 4000 bytes. Keys may not contain the following characters `. $ # [ ] /`"
          },
          "hiddenDevices": {
            "type": "object",
            "description": "A dictionary of device keys that should be hidden from the event. The keys are the device keys, and the values are `true` or `false`."
          }
        },
        "required": ["companyKey", "name"]
      },
      "VideoClip": {
        "description": "A video clip generated for a moment",
        "type": "object",
        "x-examples": {},
        "properties": {
          "key": {
            "type": "string",
            "minLength": 1,
            "description": "the clip identifier"
          },
          "rank": {
            "type": "integer"
          },
          "thumbnailURL": {
            "type": "string",
            "minLength": 1
          },
          "videoURL": {
            "type": "string",
            "minLength": 1
          },
          "downloadURL": {
            "type": "string",
            "minLength": 1
          },
          "shortUrl": {
            "type": "string",
            "minLength": 1
          },
          "views": {
            "type": "integer"
          },
          "orientation": {
            "type": "string",
            "minLength": 1
          },
          "thumbnailSizes": {
            "type": "string",
            "minLength": 1
          },
          "startTime": {
            "type": "integer"
          },
          "endTime": {
            "type": "integer"
          }
        },
        "required": [
          "key",
          "thumbnailURL",
          "videoURL",
          "downloadURL",
          "shortUrl",
          "views",
          "orientation",
          "thumbnailSizes",
          "startTime",
          "endTime"
        ]
      },
      "Moment": {
        "description": "A moment in a given Sporfie Event, capturing the action at a certain time.\nAll camera angles captured at the same time are gathered in the moment.",
        "type": "object",
        "x-examples": {},
        "properties": {
          "key": {
            "type": "string",
            "minLength": 1,
            "description": "The moment's identifier"
          },
          "momentStatus": {
            "type": "string",
            "minLength": 1,
            "description": "The processing status of the moment"
          },
          "momentStartTime": {
            "type": "integer",
            "description": "The start time of the moment (UTC, epoch in milliseconds)"
          },
          "scoreStreamEntryKey": {
            "type": "string",
            "description": "Identifier of the entry in the score stream matching this moment. Allows finding the value of the score at that time in the game."
          },
          "videoClips": {
            "type": "array",
            "description": "The video clips generated for this moment",
            "uniqueItems": true,
            "items": {
              "$ref": "#/components/schemas/VideoClip"
            }
          },
          "players": {
            "type": "array",
            "description": "Player information",
            "items": {
              "$ref": "#/components/schemas/Player"
            }
          },
          "metadata": {
            "type": "object",
            "description": "A dictionary of custom fields. Its JSON string representation (UTF-8) may not exceed 500 bytes. Keys may not contain the following characters `. $ # [ ] /`"
          }
        },
        "required": ["key", "momentStatus", "momentStartTime", "videoClips"]
      },
      "MomentSingle": {
        "description": "A moment in a given Sporfie Event, capturing the action at a certain time.\nAll camera angles captured at the same time are gathered in the moment.",
        "type": "object",
        "x-examples": {},
        "properties": {
          "key": {
            "type": "string",
            "minLength": 1,
            "description": "The moment's identifier"
          },
          "eventKey": {
            "type": "string",
            "minLength": 1,
            "description": "The identifier of the event this moment is associated with"
          },
          "momentStatus": {
            "type": "string",
            "minLength": 1,
            "description": "The processing status of the moment"
          },
          "momentStartTime": {
            "type": "integer",
            "description": "The start time of the moment (UTC, epoch in milliseconds)"
          },
          "score": {
            "$ref": "#/components/schemas/Score"
          },
          "videoClips": {
            "type": "array",
            "description": "The video clips generated for this moment",
            "uniqueItems": true,
            "items": {
              "$ref": "#/components/schemas/VideoClip"
            }
          },
          "players": {
            "type": "array",
            "description": "Player information",
            "items": {
              "$ref": "#/components/schemas/Player"
            }
          },
          "metadata": {
            "type": "object",
            "description": "A dictionary of custom fields. Its JSON string representation (UTF-8) may not exceed 500 bytes. Keys may not contain the following characters `. $ # [ ] /`"
          }
        },
        "required": ["key", "eventKey", "momentStatus", "momentStartTime", "videoClips"]
      },
      "MomentUpdate": {
        "description": "A moment update.",
        "type": "object",
        "x-examples": {},
        "properties": {
          "score": {
            "type": "object",
            "description": "The score information associated with this moment in time. Must contain the `timeStamp` field but may otherwise contain any other sport-specific score information.\n**The `timeStamp` and `key` fields are reserved field names in the score object**",
            "properties": {
              "timeStamp": {
                "type": "integer",
                "description": "Absolute time of the score information (UTC, unix epoch in milliseconds)"
              }
            },
            "required": ["timeStamp"]
          },
          "players": {
            "type": "array",
            "description": "Player information",
            "items": {
              "$ref": "#/components/schemas/Player"
            }
          },
          "metadata": {
            "type": "object",
            "description": "A dictionary of custom fields. Its JSON string representation (UTF-8) may not exceed 500 bytes. Keys may not contain the following characters `. $ # [ ] /`"
          }
        },
        "required": ["key", "momentStatus", "momentStartTime", "videoClips"]
      },
      "Place": {
        "description": "A Place on which Events are scheduled.",
        "type": "object",
        "x-examples": {
          "example-1": {
            "value": {
              "key": "string",
              "companyKey": "string",
              "name": "string",
              "location": {
                "name": "string",
                "geoLoc": {
                  "lat": 0,
                  "lng": 0
                }
              },
              "sport": "string",
              "timeZoneID": "string",
              "activeEventKey": "string",
              "thumbnailURL": "string"
            }
          }
        },
        "title": "",
        "properties": {
          "key": {
            "type": "string",
            "minLength": 1,
            "description": "The unique identifier of the Place in the Sporfie system"
          },
          "companyKey": {
            "type": "string",
            "minLength": 1,
            "description": "The identifier of the company/organization this Place is associated with"
          },
          "name": {
            "type": "string",
            "minLength": 1,
            "description": "The place name"
          },
          "sport": {
            "$ref": "#/components/schemas/SportKey",
            "description": "The sport code for this Place"
          },
          "timeZoneID": {
            "type": "string",
            "minLength": 1,
            "description": "The time zone of the Place"
          },
          "location": {
            "$ref": "#/components/schemas/Location"
          },
          "activeEventKey": {
            "type": "string",
            "minLength": 1,
            "description": "The key of the currently active event on this Place"
          },
          "thumbnailURL": {
            "type": "string",
            "minLength": 1,
            "description": "The URL of the thumbnail of the Place"
          }
        },
        "required": ["key", "companyKey", "name", "sport", "timeZoneID", "location"]
      },
      "Location": {
        "description": "A geo location",
        "type": "object",
        "x-examples": {},
        "properties": {
          "name": {
            "type": "string",
            "minLength": 1,
            "description": "The usual name of the location"
          },
          "geoLoc": {
            "type": "object",
            "required": ["lat", "lng"],
            "description": "Geographic coordinates",
            "properties": {
              "lat": {
                "type": "number",
                "description": "Latitude"
              },
              "lng": {
                "type": "number",
                "description": "Longitude"
              }
            }
          }
        },
        "required": ["name", "geoLoc"]
      },
      "ScopedCompany": {
        "description": "A trimmed-down representation of a Company/organization belonging to a Scope.",
        "type": "object",
        "title": "ScopedCompany",
        "properties": {
          "key": {
            "type": "string",
            "minLength": 1,
            "description": "The unique identifier of the Company/organization"
          },
          "name": {
            "type": "string",
            "description": "The Company/organization's name"
          },
          "slug": {
            "type": "string",
            "description": "The Company/organization's slug"
          },
          "logoURL": {
            "type": "string",
            "description": "The URL of the Company/organization's logo"
          },
          "location": {
            "$ref": "#/components/schemas/Location"
          }
        },
        "required": ["key"]
      },
      "MediaFile": {
        "description": "A recording of the stream. Usually covers the whole event, but in case of network issues during the event, may be only a partial recording.\n",
        "type": "object",
        "x-examples": {},
        "properties": {
          "key": {
            "type": "string",
            "minLength": 1,
            "description": "The unique identifier of the MediaFile in the Sporfie system"
          },
          "startTime": {
            "type": "integer",
            "description": "The start time of the recording (UTC, epoch in milliseconds)"
          },
          "thumbnailURL": {
            "type": "string",
            "minLength": 1,
            "description": "The thumbnail for the MediaFile"
          },
          "videoURL": {
            "type": "string",
            "minLength": 1,
            "description": "The video URL"
          },
          "downloadURL": {
            "type": "string",
            "minLength": 1,
            "description": "A URL pointing to the same video in a format that is guaranteed to be downloadable."
          },
          "status": {
            "type": "string",
            "minLength": 1,
            "description": "The processing status of the MediaFile",
            "enum": ["m3u8_uploaded", "mp4_processing", "mp4_processed", "error_unknown"]
          },
          "deviceID": {
            "type": "string",
            "description": "The unique identifier of the device that has streamed this content (used to hide the content of that device in the Event)"
          }
        },
        "required": ["key", "startTime", "thumbnailURL", "videoURL", "status", "deviceID"]
      },
      "LiveStream": {
        "title": "LiveStream",
        "type": "object",
        "description": "An ongoing live stream",
        "properties": {
          "thumbnailURL": {
            "type": "string",
            "description": "The URL pointing to a snapshot image of the stream"
          },
          "liveURL": {
            "type": "string",
            "description": "The URL pointing to the live stream (HLS)"
          },
          "deviceID": {
            "type": "string",
            "description": "The unique identifier of the device that is streaming (used to hide the video content of that device in the Event)"
          }
        },
        "required": ["liveURL", "deviceID"]
      },
      "Score": {
        "title": "Score",
        "type": "object",
        "properties": {
          "key": {
            "type": "string",
            "description": "The unique identifier of the score entry"
          },
          "timeStamp": {
            "type": "integer",
            "description": "The timestamp at which the score data applies"
          }
        },
        "required": ["key", "timeStamp"],
        "description": "Score data (latest score when returned in the Event)\n\nContains the key identifying the entry, a timestamp and any number of other data representing the score (sport-specific). Keys may not contain the following characters `. $ # [ ] /`"
      },
      "WebHook": {
        "title": "WebHook",
        "type": "object",
        "description": "WebHook registration configuration",
        "properties": {
          "url": {
            "type": "string",
            "description": "The URL our system will call when a change occurs"
          },
          "contentType": {
            "type": "string",
            "description": "The Content-Type to use in the webhook call. `json` is the only supported value at this point."
          }
        },
        "required": ["url", "contentType"]
      }
    }
  }
}
