Skip to content
GigOps.AI

Admin

API keys and webhooks

The GigOps API lets your own tools (a booking spreadsheet, a data warehouse, an agency's system) read your company's tours, shows, venues, bookings, ticket counts, budget summary and crew directory, ask a venue for a hold and post ticket counts. Webhooks do the opposite: GigOps posts an event to your server the moment something happens. Both are on Users & access > Developers, and both are for Company Admins (the Owner and Company Admin access levels). There is no charge for either.

How do I make an API key?

  1. Open Users & access and choose the Developers tab.
  2. Under API keys, choose New API key.
  3. Give it a Name you will recognise later, like "Booking spreadsheet".
  4. Tick the Scopes it needs, and nothing more. Each scope reads one kind of record (see "Which scopes are there?").
  5. Pick when it Expires (never, 30 days, 90 days or a year) and, if you like, its Requests a minute (10 to 1000; 120 when left blank).
  6. Choose Create key, then Copy key.

The key starts with `gk_` and is shown only this once. GigOps keeps a fingerprint of it, never the key itself, so nobody (GigOps included) can show it to you again. If you lose it, revoke it and make a new one. A company can have 25 live keys.

Which scopes are there?

A request outside the key's scopes answers 403 and names the scope it needed.

What can a key see?

A key acts as your company through the seat of the Company Admin who made it. It sees your company's records only (another company's ids answer 404), and the same per-person module settings apply as in the app: if that person's Budget is set to Off, the key's budget summary is refused too. If that person stops being a Company Admin here, or leaves the company, every key they made stops working; a Company Admin makes a new one. Answers carry only the fields listed in the API reference: never passwords, share-link tokens, pay rates or anyone's private notes.

How do I call the API?

Send the key in the `Authorization` header. The Base URL is shown on the Developers tab (it ends in `/api/v1`); the examples below use it as `$BASE`. Every answer is JSON. Lists come back as `{ "data": [...], "total", "limit", "offset", "has_more" }` and take `limit` (up to 500) and `offset`; one record comes back as `{ "data": {...} }`.

curl $BASE \
  -H "Authorization: Bearer gk_your_key"

curl "$BASE/shows?tour_id=12&from=2027-06-01&to=2027-08-31" \
  -H "Authorization: Bearer gk_your_key"

curl "$BASE/budget/summary?tour_id=12" \
  -H "Authorization: Bearer gk_your_key"

curl -X POST $BASE/counts \
  -H "Authorization: Bearer gk_your_key" -H "Content-Type: application/json" \
  -d '{"show_id": 345, "sold": 1620, "gross": 64800, "currency": "USD"}'

curl -X POST $BASE/avails/77/hold-requests \
  -H "Authorization: Bearer gk_your_key" -H "Content-Type: application/json" \
  -d '{"date": "2027-09-09", "tour_id": 12, "note": "Two nights if the 10th opens up"}'

The other reads, after `/api/v1`, are `/tours`, `/tours/{id}`, `/shows/{id}`, `/venues`, `/venues/{id}`, `/avails`, `/avails/{venueId}`, `/bookings`, `/bookings/{id}`, `/counts`, `/crew`, `/rentals` and `/rentals/{id}` (filter by `venue_id`, `client_id`, `from`, `to` and `status`), `/invoices` and `/invoices/{id}` (filter by `venue_id`, `client_id`, `rental_id`, `status`, and the issue date with `from` and `to`), and `/risks` and `/risks/{id}` (filter by `tour_id`, `show_id`, `venue_id` and `status`). Rentals and invoices need Rentals in the access of the person who made the key, and answer 404 for a company that is not on VenueOps; the risk register needs Planning. The full reference, with every field, is the OpenAPI 3.1 document at `/api/v1/openapi.json`, which most API tools can import.

What are the rate limits?

Each key has its own limit of requests a minute (120 unless you set another when you made it). Every answer says where you stand in the `RateLimit-Limit`, `RateLimit-Remaining` and `RateLimit-Reset` headers (seconds until the minute resets; `X-RateLimit-*` carry the same). Past the limit the API answers 429 with a `Retry-After` header: wait that many seconds and try again.

How do I revoke a key?

On Developers, choose Revoke on the key's row and confirm. Anything using it stops at once (401, "This API key was revoked"). The row stays in the list, marked Revoked, with when it was last used. An expired key answers 401 with "This API key has expired". Making and revoking keys is recorded in the company audit trail.

Can other companies read my venue's tech pack?

Only if you say so. In VenueOps, open Avails and tick Share my tech pack on the API on the Tech pack on the GigOps API card. Then any company's key can read `/api/v1/tech-packs/{your venue's page name}`: exactly what your public venue page shows (rooms and their public tech-pack fields, public contacts, preferred vendors and the list of public documents), never the wifi, the confirmed-tier fields or your calendar. Untick it and the read answers 404 again.

How do I add a webhook endpoint?

  1. On Users & access > Developers, under Webhooks, choose Add endpoint.
  2. Enter the Endpoint URL. It must be https on a public address: GigOps refuses plain http, private and internal network addresses, and anything with a password in the URL.
  3. Tick the Events to send, and add a Description if you like.
  4. Choose Add endpoint, then Copy secret.

The signing secret starts with `whsec_` and is shown only this once. Roll secret makes a new one (shown once) and signs with it from then on. A company can have 10 endpoints.

Which events are there?

Each event is small: `{ "id": "evt_...", "type", "created_at", "company_id", "data": {...} }`, where `data` carries the ids and status (for a show, its date, city, venue and status). Read the rest through the API with a key.

How do I check that a webhook came from GigOps?

Every delivery carries `X-GigOps-Event`, `X-GigOps-Delivery` (the event id, the same on every retry, so you can ignore one you have already handled), `X-GigOps-Timestamp` (seconds since 1970) and `X-GigOps-Signature`, which is `v1=` followed by the hex HMAC-SHA256 of the timestamp, a full stop and the raw request body, under the endpoint's secret. Check it against the raw body before you parse it, and refuse a timestamp more than five minutes old. In Node.js:

const crypto = require('crypto');
function fromGigOps(rawBody, headers, secret) {
  const ts = headers['x-gigops-timestamp'];
  const sig = String(headers['x-gigops-signature'] || '');
  const want = 'v1=' + crypto.createHmac('sha256', secret).update(`${ts}.${rawBody}`).digest('hex');
  const fresh = Math.abs(Date.now() / 1000 - Number(ts)) < 300;
  return fresh && sig.length === want.length && crypto.timingSafeEqual(Buffer.from(sig), Buffer.from(want));
}

Answer with any 2xx status within ten seconds. Do slow work after you answer.

What happens when my endpoint is down?

A delivery that gets no 2xx answer (an error, a redirect, a timeout) is tried again after 1 minute, 5 minutes, 30 minutes, 2 hours and 6 hours, then marked failed. After 15 failed attempts in a row the endpoint is switched off, nothing more is sent to it, and the Company Admins get a notification. Fix the endpoint, then choose Switch on on its card (that clears the failure count). On Deliveries you can see each event, when it was tried, the answer code and how long it took, and Send again a failed one.

How do I test an endpoint?

Choose Send test event on the endpoint's card. GigOps sends a `webhook.test` event, signed like any other, straight away, and tells you whether it was delivered and what came back. A test event is tried once and never counts toward switching the endpoint off. It works on a switched-off endpoint too, so you can check a fix before you switch it back on.