Introduction
The Union Database holds information related to golf clubs and their members.
Continuously the Union Database also holds information about scores of members. Scoring app has access through the API via an API account.
Document Audience
This document is for scoring apps who must post scores into the Union Database.
Definitions
There are a few definitions worth knowing about.
Club
A golf club has an official name, a short name, a number, and possibly an address.
Course
A course is the actual course created by the club. A course has one or more tees with 9 or 18 holes.
Member
A member is a person with one or more memberships. This means that the same person can have two or more memberships of different golf clubs.
Scorecard
A scorecard holds information about the player, the course, the marker, and the actual score.
Identifiers
All objects in the database have identifiers in the form of a GUID (Globally Unique Identifier).
The Scorecard object contains an External ID. This ID is supplied by the scoring app to reference a scorecard in the union database. This makes it simpler to modify a scorecard, because the scoring apps does not need to register the GUID locally.
Data format
The data format used for exchanging data through the API is JSON.
Authentication
Access to the API is done through Basic Authentication. Each vendor will be given an API account with a username and password. Each account is authorized to use a certain set of API resources.
API Set
All requests to the API must include an API Set in the URL. The API Set is equal to the username of the account unless otherwise instructed.
Base URL
The base urls for DGU is
- dgubasen.api.union.golfbox.io
- test-dgubasen.api.union.golfbox.io
Request headers
All requests to the API must include the following headers:
Content-Type: application/json
Accept: application/json
Authorization: Basic <username:password>
Token: <OAuth token>
The username:password combination must be Base64 encoded.
Token
The token for an API with player information is retrieved through the OAuth 2.0 Authorization Code Flow with PKCE. After the user logs in and grants consent, your application receives an authorization code. This code must then be exchanged for an access token via the token endpoint.
Once retrieved, the access token should be included as a variable in requests to protected API endpoints.
The token grants access based on the scopes requested during authorization (e.g. get_player.information). Be sure to store and transmit the token securely. If needed, refresh the token depending on the lifetime returned in the response.
For more details about OAuth authentication, refer to the OAuth Guide.
Error Handling
If a request fails, the API responds with standard HTTP error codes and messages. If syntax is correct, the API does not return an error — even if the data is invalid. Input is not validated.
Example:
HTTP/1.1 500 Internal Server Error
Clubs
Clubs holds basic information of a given club. Focus point on Clubs is the ID which must be used to lookup courses (See section about Courses)
Here is a list of the club info.
| Name | Type | Nullable | Remarks |
|---|---|---|---|
| ID | GUID | No | Database ID |
| UnionNumber | Integer | No | Official club number |
| Name | String | No | Official club name |
| ShortName | String | No | Three letter short name |
| AddressLine1 | String | Yes | Street name |
| AddressLine2 | String | Yes | Secondary address info, C/O |
| StreetNumber | String | Yes | Street number |
| Floor | String | Yes | Floor of build |
| Side | String | Yes | Side on floor |
| ZipCode | String | Yes | Zip code |
| City | String | Yes | City name |
| PrimaryPhone | String | Yes | Main telephone number |
| PrimaryEmail | String | Yes | Main e-mail address |
| Homepage | String | Yes | Web site address |
How do I look up club info?
You can get a list of all clubs by making the following API request.
Example Request
GET https://<base_url>/<apiset>/Clubs
You can get info about a specific club by making the following API request.
Example Request
GET https://<base_url>/<apiset>/Clubs/ADABD19C-D1EA-45CE-AF2B-8F5407D000A6
Example Response:
{
"ID": "ADABD19C-D1EA-45CE-AF2B-8F5407D000A6",
"Name": "Lübker Golf Klub",
"UnionNumber": 202,
"ShortName": "",
"AddressLine1": "Trent Jones Allé",
"AddressLine2": null,
"StreetNumber": "3",
"Floor": null,
"Side": null,
"ZipCode": "8581",
"City": "Nimtofte",
"PrimaryPhone": "38408050",
"PrimaryEmail": "info@lubker.com",
"Homepage": "www.lubker.com"
}
Courses
Courses holds basic information such as name, number of holes e.g. Courses also holds tees, there could be multiple tees with different names and assigned to different genders. Tees contains all the holes with pars, indexes and e.g.
Here is a list of the relevant course info.
| Name | Type | Nullable | Remarks |
|---|---|---|---|
| TemplateID | GUID | No | Database ID for the course |
| ClubID | GUID | No | Reference to CLUB |
| Name | String | No | Official course name |
| NumberOfHoles | Int | No | Typically 9 or 18 |
| ActivationDate | String | No | The date where the course is valid from (Format: yyyymmddThhnnss) |
| IsActive | Boolean | No | Indicates if a club course is currently active |
| IsHcpQualifying | Boolean | No | Indicates if a club course is aproved for handicap qualifying |
| IsVisible | Boolean | No | Indicates if a club course is visible |
| Version | Int | No | Incremental version number |
| ID | GUID | No | Version ID |
| Tees | [List] | No | |
| └─ Name | String | No | Name of tee |
| └─ Gender | Int | No | 1 = Female, 2 = Male |
| └─ TotalLength | Int | No | Sum of hole lengths |
| └─ CourseRating | Decimal | No | Official course rating value (format: x * 10000) |
| └─ SlopeRating | Int | No | Official slope rating value |
| └─ IsNineHole | Boolean | No | Indicates if this tee is nine holes only |
| └─ Holes | [List] | No | |
| └─ Name | String | Yes | Alternative hole number/hole name |
| └─ Number | Int | No | Official hole number |
| └─ Par | Int | No | Official par of hole |
| └─ Index | Int | Yes/No | Hole index |
| └─ Length | Int | No | Official length of hole |
| └─ IdealTime | Int | Yes | Ideal number of minutes for playing the hole |
Note: Some properties in the response are not described, because they are not relevant for scoring apps.
How do I look up club courses?
You can get a list of club courses in a club by making the following API request. The Club Database ID must be included in the URL.
Example Request
GET https://<base_url>/<apiset>/clubs/7AABAF90-9155-4552-889B-553D5CE75FC6/courses?excludeParams=tees
Example Response:
[
{
"TemplateID": "BFBD5556-7C08-4C70-99B3-0B5FFFE29994",
"ExternalID": null,
"RatedCourse": "",
"IsHcpQualifying": false,
"IsVisible": true,
"Version": 1,
"Tees": [],
"Created": "20250219T132329",
"ID": "6E07E6EA-6E6F-4615-95C0-A1837ECF7CEF",
"ClubID": "7AABAF90-9155-4552-889B-553D5CE75FC6",
"Name": "Test af ikke rated bane II",
"NumberOfHoles": 9,
"ActivationDate": "20250218T230000",
"IsActive": true
},
{
"TemplateID": "BFBD5556-7C08-4C70-99B3-0B5FFFE29994",
"ExternalID": null,
"RatedCourse": "",
"IsHcpQualifying": false,
"IsVisible": true,
"Version": 2,
"Tees": [],
"Created": "20250219T133447",
"ID": "9064AFFA-19EC-4F40-87EB-8BDAC7D7E808",
"ClubID": "7AABAF90-9155-4552-889B-553D5CE75FC6",
"Name": "Test af ikke rated bane II",
"NumberOfHoles": 9,
"ActivationDate": "20250218T230000",
"IsActive": true
},
{
"TemplateID": "BFBD5556-7C08-4C70-99B3-0B5FFFE29994",
"ExternalID": null,
"RatedCourse": "",
"IsHcpQualifying": true,
"IsVisible": true,
"Version": 3,
"Tees": [],
"Created": "20250219T134055",
"ID": "4B1513A1-531F-4AC8-BFE8-7241D0D8700F",
"ClubID": "7AABAF90-9155-4552-889B-553D5CE75FC6",
"Name": "Test af ikke rated bane II",
"NumberOfHoles": 9,
"ActivationDate": "20250218T230000",
"IsActive": true
},
{
"TemplateID": "BFBD5556-7C08-4C70-99B3-0B5FFFE29994",
"ExternalID": null,
"RatedCourse": "",
"IsHcpQualifying": false,
"IsVisible": true,
"Version": 4,
"Tees": [],
"Created": "20250219T134440",
"ID": "28577417-CF9D-40EB-90E1-2C907A0E9A9F",
"ClubID": "7AABAF90-9155-4552-889B-553D5CE75FC6",
"Name": "Test af ikke rated bane II",
"NumberOfHoles": 9,
"ActivationDate": "20250227T230000",
"IsActive": false
},
{
"TemplateID": "4CBDD644-F538-412D-B6F4-3F9C77CF3719",
"ExternalID": null,
"RatedCourse": "",
"IsHcpQualifying": true,
"IsVisible": true,
"Version": 1,
"Tees": [],
"Created": "20250331T110505",
"ID": "AC786C00-2AA6-4D96-AF45-06C33196C86E",
"ClubID": "7AABAF90-9155-4552-889B-553D5CE75FC6",
"Name": "Test par 3 WHS",
"NumberOfHoles": 9,
"ActivationDate": "20250330T220000",
"IsActive": false
},
{
"TemplateID": "1677552B-FA15-4F38-AE92-9101F7056A77",
"ExternalID": null,
"RatedCourse": "",
"IsHcpQualifying": true,
"IsVisible": true,
"Version": 1,
"Tees": [],
"Created": "20250331T110601",
"ID": "BC487BD9-AE99-4450-89DA-3FBE31E50013",
"ClubID": "7AABAF90-9155-4552-889B-553D5CE75FC6",
"Name": "Test par 3 WHS II",
"NumberOfHoles": 9,
"ActivationDate": "20250330T220000",
"IsActive": false
},
{
"TemplateID": "DAD70D9D-7D06-443B-8FF7-D704EC65C557",
"ExternalID": null,
"RatedCourse": "",
"IsHcpQualifying": true,
"IsVisible": true,
"Version": 1,
"Tees": [],
"Created": "20250618T121018",
"ID": "91149D2F-ED5C-4BF1-8759-E1ED3C46E70D",
"ClubID": "7AABAF90-9155-4552-889B-553D5CE75FC6",
"Name": "Ny 18 F9",
"NumberOfHoles": 9,
"ActivationDate": "20250531T220000",
"IsActive": false
},
{
"TemplateID": "DAD70D9D-7D06-443B-8FF7-D704EC65C557",
"ExternalID": null,
"RatedCourse": "",
"IsHcpQualifying": true,
"IsVisible": true,
"Version": 2,
"Tees": [],
"Created": "20250623T134207",
"ID": "E46D45F0-82F2-4AB2-B70C-38B490763FE5",
"ClubID": "7AABAF90-9155-4552-889B-553D5CE75FC6",
"Name": "Ny 18 F9",
"NumberOfHoles": 9,
"ActivationDate": "20250622T220000",
"IsActive": true
},
{
"TemplateID": "CA1636A2-4D6E-4078-AD38-D7F8BD23D76C",
"ExternalID": null,
"RatedCourse": "",
"IsHcpQualifying": true,
"IsVisible": true,
"Version": 1,
"Tees": [],
"Created": "20250618T121232",
"ID": "36D33C80-BED7-4175-BC53-0E2957556305",
"ClubID": "7AABAF90-9155-4552-889B-553D5CE75FC6",
"Name": "Ny 18 hullers WHS bane",
"NumberOfHoles": 18,
"ActivationDate": "20250531T220000",
"IsActive": false
},
{
"TemplateID": "CA1636A2-4D6E-4078-AD38-D7F8BD23D76C",
"ExternalID": null,
"RatedCourse": "",
"IsHcpQualifying": true,
"IsVisible": true,
"Version": 2,
"Tees": [],
"Created": "20250623T141638",
"ID": "4FC90CA7-0175-4EB8-8A5E-290DAC67C77E",
"ClubID": "7AABAF90-9155-4552-889B-553D5CE75FC6",
"Name": "Ny 18 hullers WHS bane",
"NumberOfHoles": 18,
"ActivationDate": "20250622T220000",
"IsActive": true
}
]
You can get a single club course by making the following API request. A club course can be referenced by a Club ID and then Course ID
Example Request
GET https://<base_url>/<apiset>//clubs/7AABAF90-9155-4552-889B-553D5CE75FC6/courses/CA1636A2-4D6E-4078-AD38-D7F8BD23D76C
To findt the course to use on a given day:
- Ignore Inactive courses
- For a given course (TemplateID) find the version with the latest ActivationDate which is not in the future.
Available parameters
When determining which vesion to use if there are many active, the following query parameters can be used when calling the apis above:
GET {{base_url}}/:ApiSet/Clubs/:ClubID/Courses
GET {{base_url}}/:ApiSet/Clubs/:ClubID/Courses/CourseID
Available parameters:
changedsince - format: yyyymmddTHhmmss, return the courses that changed after a specific date
active - accept 0 or 1, return courses based on Course.IsActive property, where 0 = inactive and 1 = active
sort - see tip sort
sortTee - see tip sortTee
excludeParams - exclude Course.Tees property from result by including "&excludeParams=tees" parameter
The courses can be sorted by including the sort parameter.
The parameter must follow this format: PropName:SortDirection,...
PropName can be:
Name, NumberOfHoles, ActivationDate, IsActive, IsHcpQualifying, IsVisible, Version
SortDirection must be 0 or 1, where 0 is ascending and 1 is descending.
Examples:
- Sort by highest number of holes:
&sort=NumberOfHoles:1 - Sort by active and then latest activation date:
&sort=IsActive:0,ActivationDate:1
The Course.Tees properties can be sorted by including the sortTee parameter.
The parameter must follow this format: PropName:SortDirection,...
PropName can be:
Name, Gender, TotalLength, CourseRating, SlopeRating, IsNineHole, LastUpdateDate
SortDirection must be 0 or 1, where 0 is ascending and 1 is descending.
Examples:
- Sort by longest tee:
&sortTee=TotalLength:1 - Sort by gender and then highest course rating:
&sortTee=Gender:0,CourseRating:1
Members
Every person in the database has an ID called LifeTimeID. The format of this number is [xxxxxx-xxx], where the first 6 are based on the persons birthdate, and the last 3 are an increment integer grouped by birthdate.
A person can be a member of a golf club. The relationship between a person and club is a membership. A person can also be a member of more than one club, thus having multiple memberships. Being a member in a golf club means that you get a member number, which is unique within the club. This member number has nothing to do with the lifetime ID. If we put together the official club number and the member number, we have a nationally unique reference for a member. This combination is called the ‘union ID’
Member info can be looked up by a lifetime ID or by union ID. Member info consist of both personal info and membership info. When a member is looked up the complete information including the person and all memberships is returned.
Here is a list of the member info.
| Name | Type | Nullable | Remarks |
|---|---|---|---|
| ID | GUID | No | Database ID |
| LifeTimeID | String | No | 12-digit number |
| FirstName | String | No | |
| LastName | String | No | |
| Gender | String | No | Male or Female |
| BirthDate | String | No | The official birth date (Format: yyyymmddThhnnss) |
| RightToPlay | Boolean | No | Indicates if the player has a national playing right |
| Status | Int | No | 1 = Amateur, 2 = Professional |
| Handicap | Decimal | No | (Decimal) The exact HCP the round was played off (format: x * 10000) |
| HandicapStatus | Boolean | No | 1 = Active (Old EGA hcp), 2=Inactive, 3=Normal (WHS) 4 = Frozen, 5 = FrozenUp, 6 = FrozenDown, 8 = Suspended, 9 = Unallocated. |
| Memberships | [List] | ||
| └─ ID | GUID | No | Database ID |
| └─ IsHomeClub | Boolean | No | Indicates if the membership is the home club membership |
| └─ LocalRightToPlay | Boolean | No | Indicates if the player has a local playing right |
| └─ Type | Int | No | 1 = Full, 2 = Flex, LongDistance = 3, Trial = 4, Passive = 5, JuniorWithoutCoursePermission = 6, 7 = Former |
| └─ UnionID | String | No | Combination of the Club Number and the Member Number, e.g. 88-534 |
| └─ Club | Object | Club info of the membership club | |
| └─ ID | GUID | No | Database ID of the club |
| └─ Name | String | No | Official name of the club |
| └─ ShortName | String | No | Short version of the club name |
| └─ UnionNumber | Int | No | Official club number |
| └─ HomeClub | Object | Club info about the home club (same as membership club if IsHomeClub) | |
| └─ ID | GUID | No | Database ID of the club |
| └─ Name | String | No | Official name of the club |
| └─ ShortName | String | No | Short version of the club name |
| └─ UnionNumber | Int | No | Official club number |
How do I look up member info?
This is dependent on your access level and agreement.
- If you represent a given golf club and have been given access to all members without their consent by the club then you can look up members in that (or those) club(s).
- If you are an independent actor you will need player consent to access their information. That is given through the OAuth login and accompanying token - refer to the OAuth Guide.
Re point 1:
You can get info about a specific member in a club you are certified to access by making the following API request. You can refer to the member by • lifetimeID • unionID
Example Request
GET https://<base_url>/<apiset>/Clubs/Golfer?lifetimeID=300191-001?unionID=202-331
Example Response:
{
"ID": "86A8D54D-4B90-4145-9583-0B1CD2766869",
"LifeTimeID": "300191-001",
"FirstName": "Nikolaj Bille",
"LastName": "Nielsen",
"Gender": "Male",
"BirthDate": "19910130T000000",
"RightToPlay": true,
"Status": 1,
"PlayerStatus": 1,
"Handicap": "340000",
"HandicapStatus": 1,
"Memberships": [
{
"ID": "ADF707B0-AA02-408E-9687-B41AEA0DFDE7",
"IsHomeClub": true,
"LocalRightToPlay": true,
"Type": 1,
"UnionID": "202-331",
"HomeClub": {
"ID": "ADABD19C-D1EA-45CE-AF2B-8F5407D000A6",
"Name": "Lübker Golf Klub",
"ShortName": "",
"UnionNumber": 202
},
"Club": {
"ID": "ADABD19C-D1EA-45CE-AF2B-8F5407D000A6",
"Name": "Lübker Golf Klub",
"ShortName": "",
"UnionNumber": 202
}
}
]
}
Re point 2:
You can retrieve information about a specific member who has granted consent by using the token obtained during the authentication process. This is done via the following API.
Example Request
GET https://<base_url>/<apiset>/clubs/Golfer_ByAccessToken
Required Headers
Authorization: Basic <username:password>Token: <access_token>
Example Response:
{
"ID": "209A4387-F75A-4C32-B4F2-01DF6FD2996D",
"LifeTimeID": "010182-008",
"FirstName": "Ingenium",
"LastName": "Test III",
"Gender": "Male",
"BirthDate": "19800101T000000",
"Email": "nih@dgu.org",
"RightToPlay": true,
"Status": 1,
"PlayerStatus": 1,
"Handicap": "520000",
"HandicapStatus": 3,
"HandicapDato": "20210111T104421",
"Memberships": [
{
"ID": "08D1CC55-2AF1-45C2-8BB4-765A0E1B24D6",
"IsHomeClub": true,
"LocalRightToPlay": true,
"Type": 1,
"UnionID": "1016-102",
"HomeClub": {
"ID": "7AABAF90-9155-4552-889B-553D5CE75FC6",
"Name": "DGU Test Club A II",
"ShortName": "DGUA",
"Union": 1,
"UnionNumber": 1016
},
"Club": {
"ID": "7AABAF90-9155-4552-889B-553D5CE75FC6",
"Name": "DGU Test Club A II",
"ShortName": "DGUA",
"Union": 1,
"UnionNumber": 1016
}
}
]
}
Scores
All the scores that are posted to the database goes into a module called the “Scorecard Exchange”. Scorecards will then later be picked up and processed, which ultimately would trigger a handicap adjustment.
Here is a list of the scorecard info.
| Name | Type | Nullable | Remarks |
|---|---|---|---|
| ID | GUID | No | Database ID set by scoring app |
| CreateDateTime | DateTime | No | Date and time scorecard was created (Format: yyyymmddThhnnss) |
| ExternalID | String | No | ExternalID is a unique identifier created by the scoring app to track the scorecard in its own system or database. |
| HCP | String | No | (Decimal) The exact HCP the round was played off (format: x * 10000) |
| CourseHandicap | Integer | No | The course handicap the round was played off. (Spillehandicap i DK) - must be included |
| PHCP | Integer | No | If Allowances are used (justeret spillehandicap i DK). Just information - not used in calculation |
| Comment | String | No | |
| Course | Object | No | |
| └─ CourseID | GUID | Yes | Reference to Course Database ID |
| └─ ExternalID | String | Yes | Possible local ID |
| └─ ClubID | GUID | Yes | Reference to Club Database ID |
| └─ Name | String | No | Name of the course |
| └─ Country | String | No | ISO2 Country Code |
| └─ TeeID | GUID | Yes | Reference to Tee Database ID |
| └─ TeeName | String | No | Name of the tee |
| └─ TeePar | Integer | No | Total par of the holes |
| └─ TeeRating | String | No | (Decimal) Official course rating value (format: x * 10000) |
| └─ TeeSlope | Decimal | No | Official slope rating value |
| └─ Holes | [List] | No | |
| └─ Number | Int | No | Official hole number |
| └─ Par | Int | No | Official par of hole |
| └─ Index | Int | No | Hole index |
| └─ Length | Int | No | Official length of hole |
| └─ SPH | Int | No | Extra Strokes on hole from playing handicap |
| Round | Object | No | |
| └─ HolesPlayed | Integer | No | Number of holes played |
| └─ RoundType | Integer | No | 1 = General Play, 2 = Tournament |
| └─ StartTime | DateTime | No | The date and time the round was played (Format: yyyymmddThhnnss) |
| └─ TournamentName | String | Yes | Name of tournament played (if roundtype = 2) |
| └─ TournamentRoundNumber | Integer | Yes | Number of tournament round played (if roundtype = 2) |
| Result | Object | No | |
| └─ Points | [List] | No | Comma-separated list with stableford points per hole |
| └─ Strokes | [List] | No | Comma-separated list with strokes per hole (0 = ball picked up, -1 = hole not played) |
| └─ TotalPoints | Integer | No | Total number of stableford points achieved |
| └─ TotalStrokes | Integer | No | Total number of strokes used (0 if ball was picked up on any hole) |
| └─ NetDoubleBogeyGross | Integer | Yes | Total Adjusted Gross Score (total of net score limited by Net Double Bogey on each hole) |
| └─ IsQualifying | Boolean | No | Determines if the score is acceptable for handicapping purposes |
| Player | Object | No | |
| └─ FullName | String | No | The full name of the player |
| └─ HomeClubName | String | No | Name of the player’s home club |
| └─ HomeClubCountry | String | No | Country of the player’s home club |
| └─ LifeTimeID | String | No | Lifetime ID of the player |
| └─ UnionID | String | No | Union ID of the player |
| Marker | Object | No | |
| └─ FullName | String | No | The full name of the marker |
| └─ HomeClubName | String | No | Name of the marker’s home club |
| └─ LifeTimeID | String | Yes | Lifetime ID of the marker if applicable |
| └─ UnionID | String | Yes | Union ID of the marker if applicable |
How do I create scorecards?
Scorecards must all be sent to the Scorecard Exchange module. You do this by making the following API request.
- Eksempel API
- Minimum Api
- Total possible Api
[
{
"ID": "7a59ca0a-525b-4884-8161-94572c2de3a2",
"CreateDateTime": "20250625T130200",
"ExternalID": "1016-1-25062025-Yellow-18-9",
"HCP": "90000",
"CourseHandicap": 9,
"Course": {
"CourseID": "CA1636A2-4D6E-4078-AD38-D7F8BD23D76C",
"ClubID": "7AABAF90-9155-4552-889B-553D5CE75FC6",
"ClubName": "DGU Test Club A II",
"TeeID": "629BDEEC-5D1F-4309-861E-08B072D9509A",
"TeeName": "2_Yellow",
"TeePar": 72,
"TeeSlope": 119,
"TeeRating": "718000"
},
"Marker": {
"FullName": "Jonas Meyer Jensen",
"LifeTimeID": "010156-012",
"UnionID": "1016-100"
},
"Result": {
"Strokes": [6, 5, 5, 5, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5, 5, 5, 5, 5],
"TotalStrokes": 90,
"NetDoubleBogeyGross": 90,
"IsQualifying": true
},
"Round": {
"HolesPlayed": 18,
"RoundType": 1,
"StartTime": "20250622T145700"
},
"Player": {
"FullName": "Nick Hüttel",
"HomeClubName": "DGU Test Club A II",
"HomeClubCountry": "DK",
"LifeTimeID": "160575-026",
"UnionID": "1016-1"
}
}
]
[
{
"CreateDateTime": "20250616T090200",
"ExternalID": "1016-1-16062025-Yellow-18-1",
"HCP": "90000",
"CourseHandicap": 9,
"Course": {
"CourseID": "CA1636A2-4D6E-4078-AD38-D7F8BD23D76C",
"ClubID": "7AABAF90-9155-4552-889B-553D5CE75FC6",
"TeeID": "629BDEEC-5D1F-4309-861E-08B072D9509A"
},
"Marker": {
"FullName": "Jonas Meyer Jensen",
"LifeTimeID": "010156-012",
"UnionID": "1016-100"
},
"Result": {
"Strokes": [6, 5, 0, 5, 5, 5, 5, 5, 4, 5, 5, 5, 5, 5, 0, 5, 5, -1],
"IsQualifying": true
},
"Round": {
"HolesPlayed": 18,
"RoundType": 1,
"StartTime": "20250616T115700"
},
"Player": {
"UnionID": "1016-1"
}
}
]
[
{
"ID": "00000000-0000-0000-0000-000000000000",
"CreateDateTime": "20250626T105455",
"ExternalID": "string",
"HCP": 0,
"CourseHandicap": 0,
"PHCP": 0,
"Comment": "string",
"Course": {
"CourseID": "00000000-0000-0000-0000-000000000000",
"ExternalID": "string",
"Name": "string",
"Country": "string",
"ClubID": "00000000-0000-0000-0000-000000000000",
"ClubName": "string",
"TeeID": "00000000-0000-0000-0000-000000000000",
"TeeName": "string",
"TeePar": 0,
"TeeSlope": 0,
"TeeRating": 0,
"Holes": [
{
"Number": 1,
"Index": 0,
"Par": 0,
"Length": 0,
"SPH": 0
}
{
"Number": 2,
"Index": 0,
"Par": 0,
"Length": 0,
"SPH": 0
}
.....
]
},
"Marker": {
"FullName": "string",
"HomeClubName": "string",
"LifeTimeID": "string",
"UnionID": "string"
},
"Result": {
"Strokes": [
0
],
"Points": [
0
],
"TotalStrokes": 0,
"TotalPoints": 0,
"NetDoubleBogeyGross": 0,
"IsQualifying": true
},
"Round": {
"HolesPlayed": 0,
"RoundType": 0,
"StartTime": "20250626T105455",
"TournamentName": "string",
"TournamentRoundNumber": 0
},
"Player": {
"FullName": "string",
"HomeClubName": "string",
"HomeClubCountry": "string",
"LifeTimeID": "string",
"UnionID": "string"
}
}
]
Error in scorecard
If the submitted data contains errors that prevent a valid handicap calculation, no handicap will be calculated. The API simply relays the data you provide—there is no validation, as ScorecardExchange acts as a pass-through to the WHS server. For example, if you submit an incorrect TeeID (e.g. by altering a digit in an otherwise valid course or club GUID), the API will echo back the data, but the scorecard will not appear in the player's record. It is therefore essential to always submit accurate and valid information.
How do I see all available APIs?
Log in with your username and password here:
https://test-dgubasen.api.union.golfbox.io/login.aspx
https://dgubasen.api.union.golfbox.io/login.aspx
This will show the Swagger documentation for the available APIs for your account
Test data
To test player information API's the following testusers can be used (PW is needed to login as player and get token)
| UnionID | PW | Name | Token |
|---|---|---|---|
| 1016-500 | DGU1234 | Test User 1 | Use OAuth account to fetch Token |
| 1016-501 | DGU1234 | Test Junior User 2 | |
| 1016-502 | DGU1234 | Test User 3 | |
| 1016-503 | DGU1234 | Test User 4 | |
| 1016-3 | gb1234 | Test Testesen | Without OAuth account: nkwHZozarin3vzSqwOJsSa2FXQcJniUtE_RUF42t3bI |
| 1016-100 | msl1234 | Jonas | |
| 1016-101 | 1234 | Morten | |
| 1016-102 | 1234 | Ingenium Test | |
| 1016-105 | gb1234 | Test Medlemstype | |
| 1016-15 | SG1234 | Tanja Lewis | |
| 1016-41 | gb1234 | Test Testesen |
To get couses look up "Ocean View Golf Club DGU" as they have the most courses in the test database
Alternatively "DGU Test Club A II" which also have courses.
Support
If you have questions or need help, contact Dansk Golf Union:
Email: it@dgu.org