Get started with the REST API

Create a REST API key, send your first request, and learn how scopes, filtering, paging, errors, and rate limits work.

Written By Melanie Gannone (Super Administrator)

Updated at October 22nd, 2026

The TripWorks REST API lets your code read and change your account's data over HTTPS. You create an API key, choose what it can access, and send requests to your own TripWorks address. This article takes you from a new key to a first working request, and explains the rules that apply to every request: access, filtering, paging, errors, and limits.

Before you begin. Creating REST 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, you don't have that permission yet, so ask an account admin to grant it to you.
Learn how to manage permission groups

In this article

  • What you can read and change through the API
  • How to create a key and copy it safely
  • How to send your first request
  • How scopes, filtering, sorting, and paging work
  • What errors, decisions, and rate limits look like

What can you do with the REST API?

The API is organized by object, such as bookings, customers, and locations, and most objects support the usual create, read, update, and delete operations. TripWorks calls an activity an experience in the API. To see how trips, trip orders, bookings, and customers fit together, read How TripWorks data fits together. Examples of what you can work with:

  • Bookings and trips. List and get bookings, add or remove a booking, set a booking's status for one booking or several, mark waivers signed, and read each booking's add-ons, custom fields, products, resources, and waivers. List and get trips, and read the manifest.
  • Guests. Create, update, delete, and merge customers. List and manage reviews. Read phone calls and call tags.
  • Your catalog. Create and manage experiences (including their waiver configurations), locations, restrictions, waiver types, promo codes, and gift cards (including activating and reloading them).
  • Notes and sources. Create and manage trip notes and trip sources.
  • Partners. Create and manage resellers.
  • Reports and history. Run the Payment Detail and Sales Detail reports, and read the audit log.
  • Your team. List and update team member profiles.

The API reference lists every object and operation and is always current, so check it for the full list.

Create an API key

  1. In TripWorks, go to Setup Integrations and open the REST API card.
  2. On the Keys tab, select Create key.
  3. Enter a Name that says what the key is for, such as Internal Reporting or Mobile App.
  4. Under Permissions, set each object to None, Read, or Write. Hover the question mark next to an object to see exactly what that level allows.
  5. Select Create key, then select Copy when your new key appears.

A new key is shown exactly once. TripWorks stores it securely and can't show it again or recover it. Copy it into your secrets manager right away. If you lose it, create a new key.

Each key belongs to one account, so the key itself decides whose data a request can see or change. Give each integration its own key with only the access it needs. That way you can rotate or delete one without breaking the others. See How API keys and access work for how to choose permissions.

Send your first request

Send the key as a bearer token to your account's own address. Every account has its own subdomain, so requests go to https://your-account.tripworks.com.

curl https://your-account.tripworks.com/rest/gift-cards \
  -H "Authorization: Bearer tw_xxxxxxxxxxxxxxxxxxxx"

Every response includes a success boolean. A list response puts its rows under the object's own name (such as gift_cards or locations) next to a meta object with per_page, has_more, and next_cursor.

To try requests without writing code, open the API reference tab on the REST API card. Each object lists its operations, and a playground lets you paste your key as the bearer token and send a real request. A curl button gives you the same request for a terminal. Your developer can also read the public reference at api-docs.tripworks.com, or load the OpenAPI document into their tools.

How do scopes work?

A scope is a permission granted to a key, per object and per direction, such as gift-cards.read and gift-cards.write. You choose them when you create the key, and you can narrow them to exactly what the integration needs.

  • A request with no key, or a malformed one, gets a 401.
  • A valid key without the right scope for the request gets a 403.
  • To change a key's access, open it on the Keys tab and select Save changes.
  • To replace a key's token, select Rotate key. Anything still using the old token stops working.
  • To remove a key, open it and select Delete key.

How do you filter, sort, and page results?

Filtering. A bare ?field=value means equality. Every other comparison uses brackets, as in ?field[op]=value, with the operators contains, begins_with, gte, and lte. Each field accepts only the operators it declares, and an unsupported one is rejected with a 422. For example, find customers by part of an email address:

GET /rest/customers?email[contains]=jordan

Or list reserved trips from a date onward, newest first:

GET /rest/trips?trip_status=reserved&sale_date[gte]=YYYY-MM-DD&sort=-sale_date

Sorting. Use ?sort=field for ascending or ?sort=-field for descending. Each list accepts only the sort fields it declares, and anything else gets a 422.

Paging. Paging uses a cursor, not page numbers. Set ?per_page=N (each object has its own maximum) and pass ?cursor= with the meta.next_cursor from the previous response. Keep going while meta.has_more is true. A cursor reused with a different sort gets a 422 instead of returning the wrong page.

What do errors look like?

A failed request includes a human-readable message and a structured error object with a stable code. Branch on the code, not on the message text, because the wording can change. See Handle errors and decisions in the REST API for the codes and a worked example.

  • 401: no key, or a malformed key.
  • 403: the key lacks the scope for this request.
  • 409: TripWorks needs a decision before it can finish. See the next section.
  • 422: the request was understood but a field, filter, or sort isn't valid. The response lists each field that failed.

What happens when TripWorks needs a decision?

Some actions need a choice that TripWorks can't make for you. Adding guests to a trip that has voucher codes is one example: you decide whether to reapply a voucher or keep the bookings as they are. Instead of guessing, TripWorks stops and asks.

  1. Send the request as usual, for example POST /rest/bookings.
  2. If a choice is needed, TripWorks replies with 409 and the error code decision_required, with a list of decisions. Each one has a kind and a context that describes the choice.
  3. Send the same request again with your answers in decisions, keyed by kind.

For a voucher decision, the answer looks like this. The strategy must be exactly REAPPLY or KEEP_AS_IS, and tripVoucherCodeId must be a voucher code on that trip.

{
  "decisions": {
    "voucher_reapply": { "strategy": "REAPPLY", "tripVoucherCodeId": 42 }
  }
}

Nothing is saved until every decision is answered. An answer that isn't recognized is refused with a 422 before anything is created. Add "dry_run": true to run every check, including capacity and your answers, without saving anything.

What are the rate limits?

Limits stop runaway code from flooding the system. If you hit one, your code usually needs to fetch less often, for example by not checking every few seconds.

  • Reads: 200 requests a minute and 3,000 an hour, per key.
  • Writes: 65 requests a minute and 1,000 an hour, per key.
  • All keys on one account: 400 requests a minute together.

A request over a limit is rejected with a 429. The Limits tab on the REST API card shows each key's usage against these numbers, and the Logs tab lists your API calls and security events. To learn about changes instead of checking for them, use webhooks. For habits that keep an integration fast, see Build integrations that stay fast and efficient, and to review requests, see Monitor and troubleshoot API activity.

Examples

  • Find a guest by email. Send GET /rest/customers?email[contains]=jordan and read the matching customers.
  • List this month's reserved trips. Send GET /rest/trips with trip_status=reserved and a sale_date[gte] filter, sorted with sort=-sale_date.
  • Find bookings with unsigned waivers. Send GET /rest/bookings?booking_waiver_status=unsigned.
  • Mark a guest's waivers signed after they sign on paper. Send POST /rest/bookings/{id}/mark-waivers-signed.
  • Issue a gift card from your own checkout. Send POST /rest/gift-cards, then POST /rest/gift-cards/{id}/activate.
  • Leave a note on a trip. Send POST /rest/trip-notes so the note appears for your team.
  • Preview a booking before you create it. Send POST /rest/bookings with dry_run set to true and read the checks that would run.

Frequently asked questions

How do I get a TripWorks API key?

Go to Setup → Integrations, open the REST API card, and select Create key on the Keys tab. Name the key, choose what each object allows, and select Create key again. Copy the key when it appears, because TripWorks shows it only once.

I lost my API key. Can TripWorks send it to me again?

No. TripWorks stores keys securely and can't show or recover one after it is created. Create a new key with the same permissions, switch your integration to it, and delete the old key. If you suspect a key was exposed, select Rotate key on it, which replaces the token and stops the old one from working.

What is the address for API requests?

Requests go to your account's own subdomain, in the form https://your-account.tripworks.com/rest/ followed by the object, such as /rest/locations. The key you send identifies the account, so one key never sees another account's data.

Why do I get a 403 when my key is valid?

A 403 means the key is real but doesn't have the scope for that request. For example, a key set to Read for gift cards can list them but can't create one. Open the key on the Keys tab, change the object's access to Write, and select Save changes.

Does the API support page numbers?

No. Lists use cursor paging. Set per_page, read meta.next_cursor from each response, and send it as cursor on the next request until meta.has_more is false. Cursors are tied to the sort you used, so keep the same sort while paging.

What does a 409 decision_required response mean?

TripWorks needs a choice from you before it can finish the action, such as whether to reapply a voucher. The response lists each decision. Send the same request again with your answers in decisions, keyed by each decision's kind. Nothing is saved until every decision is answered.

Can I test a request without changing real data?

For actions that support it, such as adding a booking, send dry_run: true. TripWorks runs every check and saves nothing. For reads, the playground on the API reference tab sends real requests with your key, so use a key limited to Read while you explore.

Should I use the REST API or webhooks?

Use the REST API when your code needs to ask for data or make a change. Use webhooks when you want TripWorks to tell you the moment something happens, so you don't have to keep checking. Many integrations use both: a webhook to learn that a booking changed, and the REST API to read its details.

Can I use an AI assistant instead of writing code?

Yes. If you want answers and changes in plain English rather than a custom integration, connect Claude, ChatGPT, or Gemini. See Connect TripWorks to your AI assistant (MCP). For a no-code way to send events to other apps, see Set up your Zapier integration.

Built for attractions, tours & activities

Build on top of your booking data

See how attractions, tours, and activities connect their booking data to the tools they already use with TripWorks. 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 →