Charter Boats
Charter Boats API

Authentication

How API keys work across the Charter Boats developer surfaces

Authentication depends on which surface you're calling:

SurfaceBaseAuth
Discovery API/api/ai/*None — public, rate-limited. A key is optional
MCP server/mcpNone — public
Agent API/api/agent/*Logged-in agent session — not a keyed surface
Operator API — reads/api/* (GET)API key on every call
Operator API — writesPOST /import/boat, DELETE /boats/:idAPI key, plus ownership of the boat/company
iCal feeds/calendar/:boatId/export.ics, /calendar/company/:companyId/export.icsNone — calendar apps can't send headers

The Discovery API, the MCP server and the iCal feeds need no credentials. Everything else under /api/* — boats, pricing, fees, locations, POIs, passages, sea routing, features, manufacturers — expects your key in the X-API-Key header on every request, reads included.

When do you actually need the key?

CallKey needed?
Any Operator API or Places & Data endpoint, from your serverYes — on every call
Import a boat (POST /import/boat)Yes — and the boat is created under your account
Delete a boat (DELETE /boats/:id)Yes — and you must be an admin or owner of the boat's company
iCal feedsNo
Discovery API (/api/ai/*) and /mcpNo — optional (see below)
# Reads carry the key
curl "https://charter.boats/api/boats?limit=5" \
  -H "X-API-Key: YOUR_API_KEY"
 
# So do writes — with a JSON body, send the Content-Type too
curl -X POST https://charter.boats/api/import/boat \
  -H "X-API-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ ... }'

What happens without a valid key:

  • No key — our bot protection stops the request before it reaches the API and answers with an HTML 403 page, not JSON. If you see HTML where you expected JSON, check the header is being sent.
  • A key that isn't real401 Invalid API key. Keys are checked on every call, not just on writes.
  • A malformed key — treated like no key: bot protection answers the HTML 403.

Every keyed call is recorded against your account, so we can see your usage when you ask about it.

Browsers on other websites

Call the API from your server. Browser requests from another website are not supported: responses carry no CORS headers, so the browser refuses to hand them to your page — and a key in client-side code is a leaked key anyway. The single exception is GET /api/locations (the exact path — the location autocomplete index), which answers cross-origin so the embeddable search widget's location box works. Anything else: proxy it through your own backend.

The Discovery API

/api/ai/* and /mcp never refuse a caller over its key. Sending one is still worthwhile: a valid API key records the call against your account, and the boat links in the response carry your affiliate ref when your account has an active affiliate profile, so bookings that start from your integration are credited to you. An invalid key is ignored — never a 401. All /api/ai/* endpoints share one rate-limit budget; past it you get 429 with a Retry-After header.

What you can't do with a key

ActionWhy
Edit an existing listing's details, prices, fees, availabilityDashboard only — tied to a logged-in session
Book and pay for a charterWebsite checkout only — session + Stripe Elements

The key gives you read access plus boat import/delete. Transactional and listing-edit actions are tied to a logged-in session on charter.boats and are not exposed as keyed endpoints.

Getting an API Key

Any registered user can generate an API key from the dashboard:

  1. Log in to charter.boats
  2. Go to Dashboard → Settings → API
  3. Read and accept the API usage terms
  4. Click Generate API Key
  5. Copy and save your key (it is only shown once)

Regenerating Your Key

If your key is compromised, you can regenerate it from the same settings page. This will immediately invalidate your old key. If the API terms have changed since you accepted them, the page asks you to accept them again before issuing a new key.

Security Best Practices

Never expose your API key in client-side code, public repositories, or anywhere it could be accessed by unauthorized parties.

Recommendations

DoDon't
Store API keys in environment variablesCommit API keys to version control
Use server-side code to make API callsInclude keys in client-side JavaScript
Rotate keys periodicallyShare keys across different applications
Use different keys for dev and production

Error Responses

Errors are JSON with the status in statusCode and the reason in message (see Response Format). The one exception is a request with no key at all: that is stopped by bot protection and comes back as an HTML 403 page.

401 Unauthorized

MessageWhen
Invalid API keyA key that doesn't belong to any account
Invalid API key formatA malformed key reached the API (from outside, bot protection usually stops it first with the HTML 403)
API key required for external requests. Include X-API-Key header.A request from outside charter.boats reached the API with no key (normally bot protection answers first with the HTML 403)
API key required. Include X-API-Key header.POST /import/boat without a key
Authentication requiredDELETE /boats/:id with neither a key nor a logged-in charter.boats session
{
  "error": true,
  "url": "https://charter.boats/api/boats?limit=1",
  "statusCode": 401,
  "statusMessage": "Server Error",
  "message": "Invalid API key"
}

403 Forbidden

MessageWhen
Not a company memberDeleting a boat whose company you don't belong to
Admin access requiredDeleting a boat in a company where you are a plain member (admin or owner required)
API key owner is not a member of the specified companyImporting with a company_id you don't belong to
(HTML page)No key sent — bot protection, not the API

On this page