Skip to main content
Parkstack

Developers

Parkstack API

Build a visitor attraction’s own website, app or screens on Parkstack. Read everything the park publishes and sell its tickets, while the park keeps editing it all in Parkstack. Payments go through Stripe to the park’s own account.

Quick start

  1. 1. Try the demo key. It reads Riverside, a demonstration park whose checkout takes no payment, so you can build everything before a park makes you a key.
  2. 2. Read from your server. Send the key as a bearer token. Answers are JSON and fresh for a minute.
  3. 3. Sell tickets. List them, show the days that can be booked, then start a checkout and send the guest to the payment page it gives you.
  4. 4. Go live with the park’s key. The park’s owner makes one in Parkstack under Park settings → Your own website, listing your website’s address if you call from browsers.

Or start from a whole website: the attraction site starter is a park’s website and ticket shop in Next.js, free to copy and change.

Demo key: pk_live_demoRiversideParkstackSiteApiKey

Terminal
curl https://api.parkstack.net/site/v1/park \
  -H "Authorization: Bearer pk_live_demoRiversideParkstackSiteApiKey"
JavaScript
// On your server: a Next.js server component, route handler or similar.
const API = "https://api.parkstack.net/site/v1";

export async function parkstack(path) {
  const response = await fetch(`${API}${path}`, {
    headers: { Authorization: `Bearer ${process.env.PARKSTACK_SITE_KEY}` },
    next: { revalidate: 60 }, // the API's answers are fresh for a minute
  });
  const body = await response.json();
  if (!response.ok) throw new Error(body.message); // { code, message }
  return body;
}

const { items: attractions } = await parkstack("/attractions");
Selling tickets
// When the guest presses Pay, on your server:
const { url } = await fetch("https://api.parkstack.net/site/v1/checkout", {
  method: "POST",
  headers: {
    Authorization: `Bearer ${process.env.PARKSTACK_SITE_KEY}`,
    "Content-Type": "application/json",
  },
  body: JSON.stringify({
    email: "guest@example.com",
    lines: [{ ticketId: "…", quantity: 2, visitDate: "2026-11-14" }],
  }),
}).then((response) => response.json());

// Then send the guest to Stripe's payment page:
redirect(url);

What it gives you

Everything the park publishes

Tickets

Checkout runs every check Parkstack’s own ticket page does: opening days, daily limits, discount codes and gift vouchers. The guest pays on Stripe’s page; card details never reach your site or Parkstack.

What people build with it

A park's own website
Designed by the park's agency, on any platform, filled from Parkstack. The park edits in Parkstack and the site shows it within a minute.
A park app
Opening times, attractions, events and buying tickets, from the same addresses.
Screens around the park
Today's hours, closed attractions and the next showtime, kept up to date.
Ticket buttons elsewhere
A booking box on a partner's or tourist board's site that sells the park's own tickets.

Rules for your site

Guests buy their tickets from the park. These rules keep what they see true and complete.

  • Show prices exactly as the API gives them (pence, as the total the guest pays). Never add VAT, fees or "from" prices of your own.
  • Never collect card details. Checkout always sends the guest to Stripe's payment page through POST /checkout.
  • Before a guest pays, link the park's Ticket terms and say who they are buying from (seller on GET /park).
  • Show the park's Privacy and Ticket terms pages with every entry in their notices, after the park's own words.
  • After payment, use Parkstack's confirmation page (the default), or read GET /orders/{orderNumber} and show every ticket's QR code.
  • While tickets.onSaleOnline is false, show nothing to buy.
  • Show refusal messages to guests as they are: they are written for them.
  • Cache answers for a minute, as Cache-Control says. A published change appears within about a minute.
  • Call the API from your server where you can. A key used from browsers must list only your own website addresses, so another site cannot borrow it. A phone app uses a key made for an app.
  • Use the same addresses as Parkstack's guest site (SITE_API_GUEST_PATHS), such as /explore/attractions/{slug}. When the park switches to its own website, Parkstack sends old links and search results to the same address on yours, and GET /redirects answers in these addresses.
  • Never invent park content, not even as sample data for previews or tests: no made-up attractions, prices, hours or events. Show only what the API returns, and leave out what is empty. For previews and tests use a real answer (the example answers in the reference are real Riverside answers). If the API cannot be reached, say so rather than filling the gap.

Limits and versions

  • Each key may make at least 120 requests a minute; larger plans allow more. Cache what you read for a minute and you will rarely come near it.
  • One address may make 1,200 a minute across every key.
  • An online order holds up to 20 tickets.
  • Version 1 only grows. Fields are added, never renamed, removed or changed in meaning. A list of values, such as error codes, may gain new ones: handle values you do not know. What has changed

Building with AI tools

Give your AI coding tool the instructions file: what Parkstack does, which addresses to use and the rules above. Save it in your project as AGENTS.md or CLAUDE.md.

Building for a park?

Ask the park’s owner to make you a key, or ask us anything about the API.