Verde for developers

Technical notes

You’re building a golf club’s website, app or back-office system and want it to take bookings through Verde. Start here: it covers which way in fits your job, how access works, the rules every call follows, and the behavior worth knowing before you ship. The endpoint-by-endpoint detail is in the Booking API reference.

Choose your way in

The booking embed - no code beyond two lines

Verde’s own booking, in a frame on the club’s website, in the club’s colors, with payments, confirmations and every club rule included. Use it unless you have a reason not to: it’s the same screens golfers use on the club’s Verde site, so it’s always complete and always current. How to add it.

The Booking API - your own screens

A JSON API, called from your server, for times, prices, bookings, cancellations and card payments across tee times, simulators, courts, rooms, dining, tournaments and private events. Use it when the booking has to live inside something you build - a mobile app, a resort system, a custom flow. Reference.

Webhooks - Verde tells you

A signed POST to your https address whenever one of the club’s bookings is made, paid for or canceled - however it was made, including at the counter and in the member app. Use them to keep another system in step instead of polling. Webhooks.

They combine: the embed for booking and webhooks into the club’s CRM is a common pairing.

Access

Everything is set up by the club, in Verde, under Website → API. Booking on outside websites has to be switched on for the club first; if it isn’t, the embed shows a short message and the API answers 402 module_inactive.

Publishable key vk_live_…For the embed. Safe in a web page: it only works on the website addresses the club lists with it.
Secret key vsk_live_…For the API. Shown once when the club creates it, then only its first characters. Either read-only (times and prices) or able to book and cancel.
Webhook signing secretShown once when the club adds your webhook address. Used to prove a webhook came from Verde.

Keep the secret key secret

  • Server only. The API refuses any request that carries a browser Origin header, so a key pasted into a web page or app bundle simply won’t work - by design.
  • One key per integration, named for who uses it, so the club can turn one off without breaking another.
  • If a key leaks, ask the club to turn it off (it stops at once) and create a new one.
  • Read-only unless you book. A key that only shows times can’t be misused to make or cancel bookings.

Conventions

Base URLhttps://www.imverde.com/api/public/v1 - exactly, with the www. The bare domain redirects, and a redirect to another host drops your Authorization header (401 unauthenticated).
AuthenticationAuthorization: Bearer vsk_live_… on every call
A memberAdd Verde-Member: vmt_… to act for a member who signed in with Verde. Without it, every booking is a guest’s.
Which clubAlways the club that owns the key. There is no way to name another club; a course id in a request picks one of the club's own courses.
MoneyWhole cents, as integers: 7500 is $75.00. Never a float.
TimesISO 8601. Instants are UTC (2026-10-03T14:20:00.000Z); dates are the club’s own calendar (2026-10-03). Each response names the club’s time zone - show times to golfers in it.
Errors{ "error": { "code": "…", "message": "…" } } with a matching HTTP status. Branch on code; show message - it’s written for a golfer.
Rate limitsPer key, per minute: 120 requests, of which 20 may make or cancel bookings. Over it: 429 with Retry-After.
RetriesEvery call that makes something needs an Idempotency-Key - one per thing you mean to make. Retrying with the same key replays the first answer (Idempotent-Replayed: true) instead of booking twice.

Quote, then book

Prices come from the club’s own rates, fees, tax and time of day - never from you. Quote first, show that price, then book with expected_total_cents. If the price moved in between, the booking is refused with price_changed rather than charging something the golfer didn’t agree to. Every club rule - how far ahead, how many players, members-only times, account-required settings - is enforced when you book, and you get the club’s own message when one says no.

Members

Bookings are a guest’s unless a member signs in with Sign in with Verde: a standard authorization-code sign-in on Verde, a code swapped on your server for a member token, and Verde-Member on later requests. How.

Tee time releases

A club opening a season of tee times at once can put them through a line: golfers wait in a waiting room and book on their turn. For those dates the API offers no times and answers release_in_progress with the waiting room’s link - send the golfer there. When the release ends, booking through the API resumes. Details.

Card payments

When a club takes payment up front, a booking call answers payment_required. Take the card like this - card details go from the golfer’s browser straight to Stripe and never touch your server or ours:

your server POST /payments { type, ...booking } -> { id, client_secret, publishable_key, stripe_account, amount_cents } your page Stripe.js: confirm the card with client_secret (and stripe_account if set) your server POST /payments/{id}/complete -> { booking } or booking_refused_refunded
  • Nothing is booked until the card succeeds, so an abandoned payment leaves nothing behind.
  • If the time was taken while the golfer was paying, the payment is refunded in full automatically and you get a message to show them.
  • If your server never calls complete - a crash, a closed tab - Verde completes the booking anyway from Stripe’s confirmation. Calling complete late, or twice, returns that same booking.
  • Not yet supported: deposits (a part-payment) and paid tournament entries. Send those golfers to the club’s own booking page or the embed.

Webhooks in practice

  • Verify every one. Recompute Verde-Signature from the raw body with the signing secret, and reject a timestamp more than five minutes old. The reference has the code.
  • Answer fast, with any 2xx, then do the work. Ten seconds without an answer counts as a failure.
  • Expect repeats and gaps in order. A retry can deliver an event twice - skip one whose Verde-Event-Id you’ve seen. Events for the same booking can arrive out of order; trust the status in the newest one you receive, or re-read the booking.
  • Failures are retried for about a day (1, 5 and 30 minutes, then 2, 6 and 12 hours). After fifty failures in a row the address is switched off, and the club sees why in Verde.
  • Addresses must be https on the public internet - a domain name, not an IP address.

Testing

Keys are live keys - there is no separate sandbox yet - so ask the club (or Verde) for a quiet part of the tee sheet or a test resource to book against, and cancel test bookings through the API when you’re done so they don’t sit on a real tee sheet. Card payments on a live club are real charges: arrange card testing with Verde before you try them. Point webhooks at a request-inspection service such as webhook.site and press Send a test in Verde.

What we promise not to change

Version 1 (/v1) only grows: new endpoints, new optional fields, new event types, new error codes. We won’t rename or remove a field, change a field’s meaning, or make an optional field required within v1. Write your code to ignore fields and event types it doesn’t know. Anything that would break an integration will be a /v2, announced well ahead.

Where to go next