The GOVIGO API uses API key authentication. Include the X-API-Key header in every request.
GET /api/golf-clubs/plans.php?golf_club_id=1 HTTP/1.1 Host: govigolf.comX-API-Key: YOUR_API_KEY
partner-type key.
Available scopes:
| Scope | Description |
|---|---|
golf_clubs:read | Read golf club / plan information |
tee_times:read | Read availability / price calendar |
reservations:read | Read quote / reservation information |
reservations:write | Create / update / cancel reservations |
integration:read / integration:write | Webhook management and golf-course-side integration (described later) |
All API responses are returned in the following common format.
{
"success": true,
"data": { ... },
"message": "",
"http_code": 200
}
| Field | Type | Description |
|---|---|---|
success | boolean | true on success, false on failure |
data | object|null | Response data (null on error) |
message | string | Message (error details on error) |
http_code | integer | HTTP status code |
| HTTP code | Meaning | Description |
|---|---|---|
400 | Bad Request | Invalid request parameters |
401 | Unauthorized | API key invalid or missing |
403 | Forbidden | Insufficient scope |
404 | Not Found | Resource does not exist (or no permission) |
405 | Method Not Allowed | Invalid HTTP method |
409 | Conflict | Resource conflict (duplicate booking, non-editable state, etc.) |
429 | Too Many Requests | Rate limit exceeded |
500 | Internal Server Error | Internal server error |
A reservation can be referenced by two keys.
| Key | Description |
|---|---|
reservation_id / id | GOVIGO internal reservation ID (integer). Returned in responses. |
external_ref | The partner system's reservation reference ID (string). If passed at creation, you can reference / update / cancel using your own ID afterwards. Recommended. |
404 Not Found. Keep external_ref unique within the same partner (a duplicate returns the existing reservation).
Checks the API key validity, owner, granted scopes and rate limit. Use it for initial connectivity testing (no scope required).
{
"success": true,
"data": {
"authenticated": true,
"owner": { "type": "partner", "id": 3, "name": "Partner A" },
"key_prefix": "a1b2c3d4",
"scopes": ["golf_clubs:read", "tee_times:read", "reservations:read", "reservations:write"],
"rate_limit": 120,
"expires_at": null,
"server_time": "2026-06-01T10:00:00+07:00"
},
"message": "pong",
"http_code": 200
}
Gets golf club details. Omit id to return a list.
| Parameter | Type | Required | Description |
|---|---|---|---|
id | integer | Optional | Golf club ID |
country | integer | Optional | Country code (0=Vietnam, 1=Thailand, 2=Japan) |
{
"success": true,
"data": {
"count": 1,
"golf_clubs": [
{
"id": 1,
"name": "Sample Golf Club",
"area": "Hanoi",
"country": 0,
"address": "123 Golf Street",
"google_map": "https://maps.google.com/...",
"course_info": "18 holes, par 72",
"cancel_policy": "Free up to 3 days before",
"cancel_policy_govigo": "..."
}
]
},
"message": "",
"http_code": 200
}
Gets the golf club plan list. The id obtained here is the golf_plan_id (required) used when booking.
| Parameter | Type | Required | Description |
|---|---|---|---|
golf_club_id | integer | Required | Golf club ID |
date | string | Optional | Only plans valid on the given date (YYYY-MM-DD) |
{
"success": true,
"data": {
"golf_club_id": 1,
"count": 1,
"plans": [
{
"id": 10,
"source": "golf_plan",
"name": "Weekday Plan",
"day_type": "weekday",
"price_local": 1500000,
"price_inbound": 2000000,
"partner_price_local": 1450000,
"partner_price_inbound": 1850000,
"apply_period": { "from": "2026-01-01", "to": "2026-12-31" },
"time_range": "06:00-10:00",
"minimum_players": 1,
"summary": "Great value weekday-only plan",
"rental_club_fee": 300000,
"rental_shoes_fee": 100000
}
]
},
"message": "",
"http_code": 200
}
price_local is the local price, price_inbound is the inbound (visitor) price. Prices are applied per player-type counts (local / inbound), which can be mixed within a single reservation. Bookings / quotes are finalized at partner_price_local / partner_price_inbound (partner prices). Only plans with bookable: true (source: golf_plan) can be booked.
Gets the golf club cancellation policy.
| Parameter | Type | Required | Description |
|---|---|---|---|
golf_club_id | integer | Required | Golf club ID |
{
"success": true,
"data": {
"golf_club_id": 1,
"cancel_policy": "Free cancellation up to 3 days before",
"cancel_policy_govigo": "Reservations via GOVIGO...",
"rules": [
{ "days_before": 3, "cancel_fee_rate": 0 },
{ "days_before": 1, "cancel_fee_rate": 50 },
{ "days_before": 0, "cancel_fee_rate": 100 }
]
},
"message": "",
"http_code": 200
}
Gets available tee-time slots for the given date. To use a tee-time slot, pass tee_time_slot_id when booking (optional).
| Parameter | Type | Required | Description |
|---|---|---|---|
golf_club_id | integer | Required | Golf club ID |
date | string | Required | Date (YYYY-MM-DD) |
{
"success": true,
"data": {
"golf_club_id": 1,
"date": "2026-03-15",
"is_closed": false,
"count": 1,
"slots": [
{
"slot_id": 101,
"tee_date": "2026-03-15",
"tee_time": "07:00",
"total_slots": 4,
"available_slots": 2,
"allow_join": true,
"plan": { "id": 10, "name": "Weekday Plan", "price": 1500000 }
}
]
},
"message": "",
"http_code": 200
}
Gets the daily minimum price for the given month (for calendar display).
| Parameter | Type | Required | Description |
|---|---|---|---|
golf_club_id | integer | Required | Golf club ID |
year | integer | Optional | Year (default: this year) |
month | integer | Optional | Month (default: this month) |
{
"success": true,
"data": {
"golf_club_id": 1,
"year": 2026,
"month": 3,
"prices": {
"2026-03-01": 1500000,
"2026-03-02": 1800000
}
},
"message": "",
"http_code": 200
}
Gets the final amount before creating a reservation. The create API recalculates with the same logic, so it matches this quote. Amounts returned are partner prices (regular price minus the partner discount).
| Parameter | Type | Required | Description |
|---|---|---|---|
golf_club_id | integer | Required | Golf club ID |
golf_plan_id | integer | Required | Plan ID (id from plans) |
local_players | integer | Required* | Number of players at local price |
inbound_players | integer | Required* | Number of players at inbound price (* at least one of the two. Total 1-20. Can be mixed) |
date | string | Optional | Play date (YYYY-MM-DD). If given, plan validity period / weekday are also validated |
rental_club | integer | Optional | Number of rental clubs |
rental_shoes | integer | Optional | Number of rental shoes |
{
"success": true,
"data": {
"plan_id": 10,
"plan_name": "Weekday Plan",
"players": {
"local": { "count": 2, "regular_unit_price": 1500000, "discount_per_player": 50000, "unit_price": 1450000, "amount": 2900000 },
"inbound": { "count": 2, "regular_unit_price": 2000000, "discount_per_player": 150000, "unit_price": 1850000, "amount": 3700000 }
},
"player_count": 4,
"minimum_players": 1,
"base_amount": 6600000,
"rental": {
"club_count": 2, "club_fee": 600000,
"shoes_count": 0, "shoes_fee": 0,
"subtotal": 600000
},
"currency": "VND",
"total_amount": 7200000,
"golf_club_id": 1
},
"message": "Quote calculated.",
"http_code": 200
}
Creates a new reservation. The request body is JSON. The amount (total_amount) is recalculated on the server from golf_plan_id, so it need not be specified in the request.
| Parameter | Type | Required | Description |
|---|---|---|---|
golf_club_id | integer | Required | Golf club ID |
golf_plan_id | integer | Required | Plan ID (id from plans) |
tee_date | string | Required | Play date(YYYY-MM-DD) |
customer_name | string | Required | Booker name |
customer_email | string | Required | Booker email |
customer_phone | string | Required | Booker phone |
players | object | Required | Player counts by price type {local?, inbound?} (can be mixed; total 1-20) |
tee_time | string | Optional | Desired tee time (HH:MM). Normal booking only. Default 08:00 |
tee_time_slot_id | integer | Optional | If specified, instantly confirmed as a real-time slot and reflected on the golf course tee sheet (obtained via available). The slot's date must match tee_date. If omitted, a normal (request) booking |
options | object | Optional | Rentals etc. {rental_club, rental_shoes} |
remark | string | Optional | Remark |
attendees | array | Optional | Companion list ({name, email?, phone?}) |
external_ref | string | Optional | Partner reservation reference ID (recommended, unique) |
POST /api/reservations/create.php HTTP/1.1
Host: govigolf.comX-API-Key: YOUR_API_KEY
Content-Type: application/json
{
"golf_club_id": 1,
"golf_plan_id": 10,
"tee_date": "2026-03-15",
"customer_name": "Taro Tanaka",
"customer_email": "tanaka@example.com",
"customer_phone": "090-1234-5678",
"players": { "local": 2, "inbound": 2 },
"options": { "rental_club": 2 },
"external_ref": "EXT-2026-00500"
}
{
"success": true,
"data": {
"reservation_id": 500,
"status": 1,
"golf_club_id": 1,
"tee_date": "2026-03-15",
"tee_time": "08:00",
"player_count": 4,
"players": { "local": 2, "inbound": 2 },
"total_amount": 7200000,
"source": "api_partner"
},
"message": "Reservation created successfully.",
"http_code": 201
}
Gets the reservation list (only reservations you created). Supports pagination.
| Parameter | Type | Required | Description |
|---|---|---|---|
golf_club_id | integer | Optional | Filter by golf club ID |
status | integer | Optional | Status code (1=requested, 2=club confirming, 3=payment requested, 4=paid/confirmed, 5=rescheduling, 6=cancel requested, 7=cancelling(no refund), 8=cancelling(refund), 9=completed, 10=completed(cancelled)) |
date_from | string | Optional | Play date start (YYYY-MM-DD) |
date_to | string | Optional | Play date end (YYYY-MM-DD) |
page | integer | Optional | Page number (default: 1) |
per_page | integer | Optional | Items per page (default: 20, max: 100) |
sort | string | Optional | Sort field (tee_date / created) |
order | string | Optional | Sort order (asc / desc) |
{
"success": true,
"data": {
"reservations": [
{
"id": 500,
"golf_club_id": 1,
"golf_club_name": "Sample Golf Club",
"customer_name": "Taro Tanaka",
"tee_date": "2026-03-15",
"tee_time": "08:00",
"player_count": 4,
"players": { "local": 2, "inbound": 2 },
"total_amount": 7200000,
"status": "1.requested",
"status_code": 1,
"source": "api_partner",
"external_ref": "EXT-2026-00500",
"created_at": "2026-03-01 10:00:00"
}
],
"pagination": {
"page": 1, "per_page": 20, "total_count": 1,
"total_pages": 1, "has_next": false, "has_prev": false
}
},
"message": "",
"http_code": 200
}
Gets reservation details. Specify either id or external_ref.
| Parameter | Type | Required | Description |
|---|---|---|---|
id | integer | one of | GOVIGO reservation ID |
external_ref | string | one of | Partner reference ID |
{
"success": true,
"data": {
"reservation": {
"id": 500,
"golf_club_id": 1,
"golf_club_name": "Sample Golf Club",
"plan_id": 10,
"plan_name": "Weekday Plan",
"customer_name": "Taro Tanaka",
"customer_email": "tanaka@example.com",
"customer_phone": "090-1234-5678",
"tee_date": "2026-03-15",
"tee_time": "08:00",
"player_count": 4,
"players": { "local": 2, "inbound": 2 },
"total_amount": 7200000,
"remark": null,
"options": { "rental_club": 2, "rental_shoes": 0 },
"status": "1.requested",
"status_code": 1,
"source": "api_partner",
"external_ref": "EXT-2026-00500",
"created_at": "2026-03-01 10:00:00",
"updated_at": "2026-03-01 10:00:00",
"attendees": [
{ "name": "Hanako Sato", "email": null, "phone": null }
]
}
},
"message": "",
"http_code": 200
}
Updates the reservation. Only the specified fields are updated. If players / options change, total_amount is recalculated on the server. players follows the same interpretation as reservation creation: omitted types are treated as 0 players (always specify counts for all types). For real-time bookings, changing the total number of players also adjusts the golf course inventory. Cancelled (status=6-8) / completed (status=9,10) reservations cannot be updated.
| Parameter | Type | Required | Description |
|---|---|---|---|
reservation_id / external_ref | integer/string | Required (one of) | Reference key of the target reservation |
players | object | Optional | Player counts by price type {local?, inbound?} (recalculates total; omitted types are treated as 0) |
options | object | Optional | Rentals etc. (recalculates amount on change) |
customer_name / customer_email / customer_phone | string | Optional | Booker info |
tee_date | string | Optional | Play date(YYYY-MM-DD). Real-time bookings (those with tee_time_slot_id) cannot be changed (cancel and re-create instead) |
remark | string | Optional | Remark |
attendees | array | Optional | Companions (full replacement if specified) |
POST /api/reservations/update.php HTTP/1.1
Host: govigolf.comX-API-Key: YOUR_API_KEY
Content-Type: application/json
{
"external_ref": "EXT-2026-00500",
"players": { "local": 2, "inbound": 1 },
"remark": "1 person cancelled"
}
{
"success": true,
"data": {
"reservation_id": 500,
"golf_club_id": 1,
"plan_id": 10,
"player_count": 3,
"players": { "local": 2, "inbound": 1 },
"total_amount": 5350000,
"status": "1.requested",
"status_code": 1,
"external_ref": "EXT-2026-00500",
"updated_at": "2026-03-02 09:00:00"
},
"message": "Reservation updated.",
"http_code": 200
}
Cancels the reservation. Specify reservation_id or external_ref. Like member bookings, it is accepted as a cancellation request (status=6) and finalized by staff. Real-time bookings automatically restore the golf course inventory. Reservations already cancelling (status=6-8) / completed (status=9,10) cannot be cancelled.
| Parameter | Type | Required | Description |
|---|---|---|---|
reservation_id / external_ref | integer/string | Required (one of) | Reference key of the target reservation |
reason | string | Optional | Cancellation reason |
POST /api/reservations/cancel.php HTTP/1.1
Host: govigolf.comX-API-Key: YOUR_API_KEY
Content-Type: application/json
{
"external_ref": "EXT-2026-00500",
"reason": "Due to schedule change"
}
{
"success": true,
"data": {
"reservation_id": 500,
"status": "cancel_requested",
"status_code": 6,
"cancelled_at": "2026-03-02T10:00:00+07:00"
},
"message": "Reservation cancelled successfully.",
"http_code": 200
}
A mechanism to notify your system of reservation status changes. Notifications are sent via HTTPS POST when events occur.
reservation.created / reservation.updated / reservation.cancelled / reservation.status_changed / *(all events)
Registers a Webhook receiving URL.
| Parameter | Type | Required | Description |
|---|---|---|---|
golf_club_id | integer | Required | Golf club ID |
url | string | Required | Webhook receiving URL (HTTPS required) |
events | array | Required | Event types to subscribe |
POST /api/integration/webhooks/subscribe.php HTTP/1.1
Host: govigolf.comX-API-Key: YOUR_API_KEY
Content-Type: application/json
{
"golf_club_id": 1,
"url": "https://your-system.com/webhook/govigo",
"events": ["reservation.created", "reservation.updated", "reservation.cancelled"]
}
{
"success": true,
"data": {
"subscription_id": 10,
"golf_club_id": 1,
"url": "https://your-system.com/webhook/govigo",
"events": ["reservation.created", "reservation.updated", "reservation.cancelled"],
"secret": "a1b2c3d4e5f6..."
},
"message": "",
"http_code": 201
}
secret is used for HMAC verification of the Webhook payload. Verify the signature on receipt to confirm authenticity.
Gets the list of registered Webhooks.
| Parameter | Type | Required | Description |
|---|---|---|---|
golf_club_id | integer | Required | Golf club ID |
{
"success": true,
"data": {
"golf_club_id": 1,
"count": 1,
"subscriptions": [
{
"id": 10,
"golf_club_id": 1,
"url": "https://your-system.com/webhook/govigo",
"events": ["reservation.created", "reservation.cancelled"],
"is_active": true,
"created_at": "2026-03-01 10:00:00",
"updated_at": "2026-03-01 10:00:00"
}
]
},
"message": "",
"http_code": 200
}
Unsubscribes a registered Webhook.
| Parameter | Type | Required | Description |
|---|---|---|---|
subscription_id | integer | Required | Subscription ID to unsubscribe |
POST /api/integration/webhooks/unsubscribe.php HTTP/1.1
Host: govigolf.comX-API-Key: YOUR_API_KEY
Content-Type: application/json
{ "subscription_id": 10 }
Sends a test notification to a registered Webhook to verify URL connectivity and signature verification.
| Parameter | Type | Required | Description |
|---|---|---|---|
subscription_id | integer | Required | Subscription ID to test |
POST /api/integration/webhooks/test.php HTTP/1.1
Host: govigolf.comX-API-Key: YOUR_API_KEY
Content-Type: application/json
{ "subscription_id": 10 }