Set up the TripWorks REST API

Create an API key under Setup, Integrations, REST API so your own software can read and update your TripWorks data. Covers scopes, rate limits, and what the API reaches.

Written By Melanie Gannone (Super Administrator)

Updated at October 21st, 2026

If you have a developer and software of your own — a website, an internal dashboard, a CRM — the TripWorks REST API lets that software read and update your account directly. You create an API key, decide what it's allowed to touch, and hand it to whoever is building the integration.

This article covers creating and scoping that key. The endpoint reference, with every field and example response, lives at api-docs.tripworks.com. It's public, so you can send it to a developer or an agency without giving them a TripWorks login.

Before you begin. Creating API keys requires the Setup integrations catalog permission. It comes with the built-in Owner group, or any custom permission group that includes it. If Integrations doesn't appear under Setup, ask an account admin to grant it to you.
Learn how to manage permission groups

In this article

  • Whether the REST API is the right choice, or whether Zapier, webhooks, or an AI assistant fits better
  • Creating an API key and choosing what it can reach
  • Checking that the key works
  • Rate limits, and what happens when you hit one
  • What the API covers today, and what it doesn't

Is the REST API the right choice?

TripWorks has four ways to connect to other software. The REST API is the most capable, and the only one that needs a developer. Choosing the wrong one can cost weeks, so it's worth a minute up front.

The question that sorts it is who is doing the work.

  • Your own software is doing the work. Use the REST API. It's the right answer for a custom booking page, a dashboard your team watches, or a sync into a system with no TripWorks connector of its own.
  • You want something to happen automatically when a booking comes in. Use Zapier if you'd rather not write code, or webhooks if you're sending data to a system you control. Both are much quicker to set up than building against the API.
  • A person wants to ask a question or make a quick change. Use an AI assistant. No code, and it follows that person's own permissions.

An API key is a standing credential for software. Nobody approves each request, and it keeps working until you deactivate it. That's exactly what an integration needs, and exactly why the scopes you grant matter.

Create an API key

1. Go to Setup Integrations REST API. 2. If the integration is switched off, turn it on. You'll see five tabs: **Overview**, **Keys**, **Limits**, **Logs**, and **API reference**. 3. Open the **Keys** tab and select **Create key**. 4. Name the key after whatever will use it — "Website booking form", "Finance dashboard". When something misbehaves six months from now, this name is how you work out what to switch off. 5. Choose what the key can reach. Each area of your account offers **None**, **Read**, or **Write**. Grant the least that will work: a dashboard that only displays numbers needs Read, and nothing else. 6. Select **Create**. The key appears **once**, on this screen. 7. Copy it somewhere safe and pass it to your developer through a password manager or secrets store, rather than email or chat.

If you lose the key

You can't look it up again. TripWorks stores only a one-way fingerprint and the last four characters, so nobody — including TripWorks support — can recover the original value. Use Rotate on the Keys tab to issue a replacement, then update wherever the old one was stored. Rotating invalidates the previous key immediately, so pick a quiet moment.

Check that it works

Your developer sends the key as a bearer token on every request:

curl https://your-account.tripworks.com/rest/locations \
  -H "Authorization: Bearer tw_your_key_here"

Replace your-account with your own TripWorks subdomain, the one you log in at. Your account is identified by that subdomain, so there's no account ID to pass anywhere.

A working request returns your locations with a meta block:

{
  "success": true,
  "locations": [ ... ],
  "meta": { "per_page": 25, "has_more": false, "next_cursor": null }
}

That's the confirmation the key is live and correctly scoped. A 401 instead almost always means the header isn't exactly Authorization: Bearer tw_… — a missing Bearer prefix is the single most common cause.

What the API covers

The API spans most of what you work with day to day: bookings, trips, customers, experiences, locations, promo codes, restrictions, gift cards, resellers, reviews, trip notes, trip sources, waiver types, your team, your manifest, your audit log, phone calls, saved reports, and aggregate analytics.

Most of those can be read, created, updated and deleted. A few are read-only by design.

What isn't available yet: live availability, payment records, and the full sell flow — checking availability, holding a slot and taking payment end to end. If your project depends on selling through the API rather than through a TripWorks booking page or widget, that isn't possible today. Better to know before you scope the work.

New resources are added regularly, and api-docs.tripworks.com is generated from the live API, so it's always an accurate list of what exists right now.

Rate limits

Limits are counted per key rather than per IP address, so an agency working from one office doesn't get throttled because a colleague is also calling the API.

Limit Allowance
Reads per minute 200
Writes per minute 65
Reads per hour 3,000
Writes per hour 1,000
All requests per minute, whole account 400

Every response carries X-RateLimit-Limit, X-RateLimit-Remaining and X-RateLimit-Reset, so a well-built integration can pace itself rather than waiting to be refused. Going over returns a 429 with a Retry-After header telling you how many seconds to wait.

The last row is the one that catches people out. That 400-per-minute ceiling is shared by every key on the account, so a noisy new integration can slow down one that had been running happily for months. When you add a second integration, watch the Limits tab for a few days.

Reading lists

List endpoints return 25 records at a time, and there's no way to ask for more. Rather than page numbers, each response includes a next_cursor; passing it back gets you the next 25.

GET /rest/customers?per_page=25
GET /rest/customers?cursor=eyJpZCI6MTIzfQ

There's deliberately no total count. On an account with hundreds of thousands of customers, counting them all on every request would be slow for everyone, so use has_more to decide whether to keep going.

Filtering puts the operator in brackets after the field name, and sorting takes a - prefix for descending order:

GET /rest/experiences?name[contains]=Sunset&sort=-created_at

When something goes wrong

Every error comes back in the same shape, with a code your developer can branch on instead of matching on text:

{
  "success": false,
  "message": "Rate limit exceeded.",
  "error": { "code": "too_many_requests" }
}
What you see What it usually means
401 unauthorized The Authorization header is missing or malformed
403 forbidden The key was rotated or deactivated, or the REST API integration is switched off
403 insufficient_scope The key is valid but wasn't granted this area — check the Keys tab
422 unknown_fields The request body includes a field that can't be written
422 invalid_cursor A cursor was reused after the sort changed, or it's gone stale — start the list again
429 too_many_requests Slow down; Retry-After says by how much

The Logs tab shows recent API activity on your account, which is usually faster than asking a developer to reproduce something.

Two examples

A dashboard on the office wall. A multi-location operator wants today's numbers on a screen in the back office. Their developer creates a key named "Ops dashboard" with Read on bookings, trips and analytics, and nothing else. Even if that key leaked, it couldn't change anything.

Customers into a CRM. A tour company syncs new customers into their marketing CRM overnight. The key has Read on customers and nothing more, it pages through with the cursor, and it runs at 2am so it isn't competing with the booking widget for the account's request budget.

Frequently asked questions

**Does the API cost extra?** No. It's included, and there's no separate API plan. **Is there a test or sandbox environment?** No. Development happens against your own account, so start with read-only scopes and add write access once the integration is behaving. **How many keys can I create?** As many as you need. A separate key per integration is good practice — if one has to be rotated, only that integration breaks. **Can I restrict a key to certain IP addresses?** Not currently. Control access through scopes instead, and keep each key as narrow as its job requires. **Does the key expire?** No. It works until you rotate or deactivate it. Rotate it periodically, and straight away if you think it's been exposed. **Someone left the company — what should I do?** Rotate any key they had access to. Keys belong to the account rather than to a person, so removing their login doesn't invalidate a key they'd already copied.

Next steps

  • Share api-docs.tripworks.com with whoever is building the integration
  • Set up webhooks if your system needs telling when something happens, rather than polling for it
  • Try an AI assistant if what you actually wanted was to ask questions about your data

Built for attractions, tours & activities

Build on top of your booking data

See how attractions, tours, and activities connect TripWorks to their own websites, dashboards, and internal tools. Book a demo and make the switch.

Can't find what you're looking for?

Our team is here to help. Reach out and we'll get back to you as soon as possible.

Contact us →