# dancerank API Dancerank.cz provides a public HTTP API for read-only access to the database of results of dancesport competitions. ## Data model - **Event**: a dancesport event, includes multiple competitions that are hosted in a single venue at a particular time. - **Competition** (shortened as **comp**): a particular dancing match where couples are marked by referees and ranked by their performance. The competition consists of multiple **rounds**. Couples participate in a subset of rounds. - **Athlete**: a person who participates in competitions, either as a man or as a lady. - **Couple**: a pair of athletes (man and lady) dancing _at a particular competition_. A better term would be "couple result". - **Referee** (adjudicator): a person who ranks couples at a competition. The set of referees is fixed for a competition and cannot change between rounds. - **Domain**: Every entity (event, competition, athlete, referee) belongs to a single domain, which corresponds to the organization from which the results are taken (such as WDSF, ČSTS, SZTS, ...). Domains are identified by short strings, for example `wdsf`, `csts`, `szts`, ... - **Triple**: a standardized classification of competitions. It consists of four elements: - **Category** (by age): `juvenile[12]`, `junior[12]`, `youth`, `under21`, `adult`, `senior[1234]` - **Class** (performance level): `m` (the highest, usually called "S"), `[abcdefgh]` (where "A" is the best and "H" is the worst), `p` (professional) - **Discipline** (kind of dance): `std` (Standard dances or their subset), `lat` (Latin dances or their subset), `10d` (all five Standard and all five Latin dances), `comb` (some subset of the standard and latin dances, used mostly at Juvenile and Junior competitions), `showlat`, `showstd`, `show` (Showdance in Latin, Standard or something else), `formlat`, `formstd`, `form` (formation dancing in Latin, Standard or something else), `solo`, `salsa`, `wheelchair`, `other`. - **Type**: `ranked` (couples obtain points into some ranklist), `cup` (results are not counted in ranklists; includes various championships), `league` (special type of competition organized by some national organizations to form a national ranklist). - Some elements may be missing (set to `null`) if they are not applicable or could not be extracted. ## API The API is exposed over HTTP and returns JSON objects (`Content-Type: application/json`). Request parameters, if any, are passed either as parts of the path or in the query string. In case of an error, an appropriate HTTP error status is sent with a short description of the error. Error = { "message": Human-readable description of the error. (string) } The base URL where the API is hosted is `https://api.dancerank.cz`. Only HTTPS is supported. By default, the returned JSON is minified. Pass query parameter "?pretty=1" in the HTTP request to return prettified, human-readable JSON. Depending on the server load, the API calls may be throttled or rejected with status 429 (Too many requests). The API may sometimes be unavailable with statuses 500, 502, 503 or 504, altough we try to minimize outages. Please consider sending an informative `User-Agent` header with your request. ## Common data types Triple = { "category": category if (string | null), "class": class id (string | null), "discipline": discipline id (string | null), "type": type id (string | null), } Date = "{yyyy}-{mm}-{dd}" Rank of a couple in a competition or in a round is usually a single integer from 1 to (number of couples), but it may be a range if multiple couples share the same place. Rank = { "begin": The first number in the range. (int) "end": The second number in the range. (int) } ## Get an event, a competition, a couple, an athlete All entities exposed in the API are identified by a string id. In general, the format of the ids is arbitrary and should not be relied on. ### Get event Obtains information about an event by its id. Request: GET /v1/events/by_id/{event_id} Response: Event Event = { "event_id": Id of the event. (string) "domain": Domain id where the event belongs. (string) "is_temporary": True if the results are not yet confirmed and may change or be removed. (bool) "dates": { "begin": The first day of the event. (Date) "end": The last day of the event (inclusive). (Date) } "location": Short textual description of the event location. (string) "title": Title/name of the event. (string) "original_url": URL with the original results (string | null) "comps": Competitions that belong to this event (array of Comp) } ### Get competition Obtains information about a competition by its identifier. Request: GET /v1/comps/by_id/{comp_id} Response: Comp Comp = { "event_id": Id of the event. (string) "comp_id": Id of the competition. (string) "domain": Same as `Event.domain`. (string) "is_temporary": Same as `Event.is_temporary`. (bool) "triple": Classification of the competition (Triple), "title": Title/name of the competition. (string) "date": Date when the competition was held. (Date) "original_url": URL with the original results. (string | null) "rounds": Information about each round. (array of CompRound) "dances": Names of the dances. (array of string) "couples": Information about each couple. (array of Couple) "referees": Information about each referee. (array of CompReferee) } CompRound = { "title": Name of this round. (string) "type": Type of marks given to couples. ("crosses" | "grades" | "absolute") "couples": Information about each couple that participated in this round. (array of CompRoundCouple) "abs_dances": Information about absolute scores of each dance; present iff type == "absolute". (array of CompAbsDance | absent) } CompRoundCouple = { "couple_id": Id of the couple. (string) "rank": Rank of the couple in this round. (Rank) "marks": Marks of this couple in this round. The mark for a given dance and referee is stored in marks[dance_idx][referee_idx]. If type == "crosses", marks are usually "X" (a cross given) or "-" (a cross not given). If type == "grades", marks are "1" to "9". In redance rounds, a "*" may appear to signify that the couple did not dance in the redance but qualified directly into second round. Other symbols may appear to signify disqualifications etc. If type == "absolute", this field is not present. (array of string | absent) "abs_total_score": Total absolute score of this couple in this round. Only present if type == "absolute". (string | absent) "abs_dance_scores": Total scores for each dance of this couple in this round. Only present if type == "absolute". (array of float | absent) "abs_area_scores": Total scores for each dance and area of this couple in this round. Only present if type == "absolute". The format of the array is abs_area_scores[dance_idx][area_idx]. The list of areas for each dance is given in CompAbsDance (CompRound.abs_dances). (array of (array of string) | absent) "abs_scores": Scores given by each referee for each dance and area (component) for this couple. Only present if type == "absolute". Some scores may be null if referees judged only a subset of areas. The format of the array is abs_scores[dance_idx][area_idx][referee_idx]. The list of areas for each dance is given in CompAbsDance (CompRound.abs_dances) (array of (array of (array of (string | null))) | absent) } CompAbsDance = { "areas": Names of judging areas (components, such as "Technique", "Movement to Music", ...). (array of string) } Couple = { "event_id": Id of the event. (string) "comp_id": Id of the competition. (string) "couple_id": Id of the couple. It is globally unique, but only appears in a single competition. The same pair of man and lady will have different couple ids at different competitions. (string) "domain": Domain of the event/competition. (string) "rank": Final rank of the couple at the competition. (Rank) "man_name": Name of the man. (string) "man_id": Athlete id of the man. (string | null) "lady_name": Name of the lady. (string) "lady_id": Athlete id of the lady. (string | null) "start_number": Start number of the couple. (string) "club": Name of the club that this couple represents at this competition. (string) "country": Country that this couple represents at this competition. (string) "comp_points": Number of points that the couple received at the competition. (int | null) "comp_fs": Number of premium points (finals or Fs) that the couple received at the competition. (int | null) "new_points": Total number of points that the couple has after the competition. (int | null) "new_fs": Total number of premium points that the couple has after the competition. (int | null) "new_class": Id of the class that the couple received at this competition. (string | null) "note": Any extra unstructured information about the couple. (string) } CompReferee = { "event_id": Id of the event. (string) "comp_id": Id of the competition. (string) "referee_id": Id of the referee. (string | null) "domain": Domain of the event/competition. (string) "name": Name of the referee. (string) "country": Country that this referee represents at this competition. (string) } ### Get athlete Obtains information about an athlete by their id. Request: GET /v1/athletes/by_id/{athlete_id} Response: Athlete Athlete = { "athlete_id": Id of the athlete. (string) "domain": Domain id of the athlete. (string) "name": Full name of the athlete. (string) "first_name": First name of the athlete. The separation into first name and last name is only approximate and may be wrong or nonsensical for some names. Please use the `name` field if possible. (string) "last_name": Last name of the athlete. The separation into first name and last name is only approximate and may be wrong or nonsensical for some names. Please use the `name` field if possible. (string) "original_url": URL with original athlete profile (string | null) "csts_idt": ČSTS IDT number of the athlete, present only if `domain` is "csts". (string | null | absent) "wdsf_min": WDSF MIN number of the athlete, present only if `domain` is "wdsf". (string | null | absent) } ### Get couple Obtains the result of a particular couple (pair of athletes at a competition). Request: GET /v1/couples/by_id/{couple_id} Response: Couple ## Listing results ### List events by date Lists events in a range of dates. Request: GET /v1/events/by_date ?begin_date= Initial date, inclusive (Date, required) &end_date= Final date, exclusive (Date, required) &domain= Limit to the given domain. If "all" or omitted, all domains are searched. (string, default "all") &full= If true, full information about the events is returned. (bool, default false) Response: EventList EventList = { "event_ids": List of event ids, always present. (array of string) "events": List of events, present only if `full` is true. (array of Event | absent) } ### List results of an athlete Lists all results of a single athlete. Note that this can be used only to find results for athletes that have an id! The list is ordered by date (decreasing). Request: GET /v1/couples/by_athlete ?athlete_id= Id of the athlete (string, required) &full= If true, full information about the couples is returned. (bool, default false) Response: CoupleList CoupleList = { "couple_ids": List of couple ids, always present. (array of string) "couples": List of couples, present only if `full` is true. (array of Couple | absent) } ### List results of a man-lady pair Lists all results of the given pair of athletes (man and lady). Note that this can be used only to find results of athletes that have an id! The list is ordered by date (decreasing). Request: GET /v1/couples/by_pair ?man_id= Athlete id of the man (string, required) &lady_id= Athlete id of the lady (string, required) &full= If true, full information about the couples is returned. (bool, default false) Response: CoupleList ## Searching The API provides a unified interface for text-based search. It can be used to find athletes, couples (results at competitions) and events. ### Search for X (generic description) Performs a textual search for X (a document). Conceptually, each document contains two types of fields: - Textual fields are sets of words (e.g. athlete name). - Categorical fields are strings from a predefined set of values (e.g. category with values "adult", "junior1", "under21", ...). A search request specifies a list of queries. Only documents that match all queries in the request are returned in the response. There are three types of queries: - Textual query matches only documents that contain all given words in the specified field. The query is specified in free text, e.g. "ginny weasley" represents the set {"ginny", "weasley"}. A query such as `lady_name`="ginny weasley" will match all documents where the field `lady_name` contains both "ginny" and "weasley". - Wildcard textual query is like the textual query, but applies to all textual queries in the document. - Filter query specifies a set of allowed values of a categorical field. The values are separated by a comma (for example `discipline`="youth,under21" matches all documents with `dicipline` equal to "youth" or "under21"). A special value "all" matches all values (thus making this query a no-op). Every text must contain at least one non-empty textual query (it can be the wildcard query). The search has simple boolean semantics: each document either matches the search or not, there is no notion of "relevance". The results are always returned in a predefined order (documented separately for each type of document). This order is also used for paging. Request: GET /v1/X/search ?search= The wildcard textual query that can match any field in the document. (string, default empty) &{field_name}= A query for the given `field_name`. The type of the query (textual/filter/boolean) is determined from `field_name`. (string, default empty) &page= Page number, starting at 1. (integer, default 1) &page_size= Size of a page; maximum page size is documented for each X. (integer, default is X-specific maximum) &full= If true, full documents are returned. (bool, default false) Response: SearchResult SearchResult = { "total_count": Total number of documents that match the query. Only a subsequence corresponding to one page is returned. (int) "page_count": Total number of pages. (int) "page": The number of the current page, starting at 1. (int) "page_size": Number of documents in one page. (int) "document_ids": List of document ids. (array of string) "documents": List of documents, only present if `full` is true. (array of X | absent) } ### Search for athletes Available fields are: - `first_name`, `last_name`: textual - `domain`: categorical Athletes are ordered by their id (ascending). Maximum page size is 30. Request: GET /v1/athletes/search?... Response: SearchResult ### Search for couples Available fields are: - `man_name`, `lady_name`, `club`: textual - `category`, `class`, `discipline`, `type`: categorical, these correspond to the fields of the `Triple` object of the competition - `domain`: categorical Couples are ordered by date (descending), competition id (ascending), couple id (ascending). Maximum page size is 50. Request: GET /v1/couples/search?... Response: SearchResult ### Search for events Available fields are: - `title`, `location`: textual - `domain`: categorical Events are ordered by date (descending), event id (ascending). Maximum page size is 30. Request: GET /v1/events/search?... Response: SearchResult ## Miscellaneous ### Get symbols Returns lists of all symbols used in triples or domains. Request: GET /v1/symbols Response: Symbols Symbols = { "domains": List of domain ids. (array of string) "categories": List of category ids. (array of string) "classes": List of class ids. (array of string) "disciplines": List of discipline ids. (array of string) "types": List of competition types. (array of string) } ### Get documentation Returns this documentation in plain text. Request: GET /v1/docs Response: this document The paths `/` and `/v1` will redirect to `/v1/docs`.