Authentication

All GuestNetworks API requests — REST and MCP alike — authenticate with a single Bearer token. This page covers how to get a key, what the key looks like, how to send it, and what rate limits apply per plan.

1. Sign up and get your API key

Create a free account at guestnetworks.com/signup. Enter your name and email, click Generate API Key, and copy the key immediately — it is shown once and never again.

Key format: every key starts with gn_live_ followed by 28 random characters. Example: gn_live_sk_xxxxxxxxxxxxxxxxxxxxxxxx. Store it in an environment variable — never hardcode it in source control.
Shell
# Store the key in your shell environment
export GN_API_KEY="gn_live_sk_xxxxxxxxxxxxxxxxxxxxxxxx"

# Verify the service is reachable (no auth required)
curl https://api.guestnetworks.com/health
# → {"status":"healthy","db":{"connected":true,"latencyMs":8},...}

2. Send the Authorization header

Include Authorization: Bearer <key> on every authenticated request. The same header works for the REST API (/api/*), the ingest endpoint (/ingest), and the MCP transport (/mcp). There is no separate key for MCP.

cURL (REST)
curl https://api.guestnetworks.com/api/venues \
  -H "Authorization: Bearer $GN_API_KEY"
TypeScript (REST)
const res = await fetch('https://api.guestnetworks.com/api/venues', {
  headers: {
    'Authorization': `Bearer ${process.env.GN_API_KEY}`,
    'Content-Type': 'application/json',
  },
});
const { data: venues } = await res.json();
Python (REST)
import os, requests

headers = {
    "Authorization": f"Bearer {os.environ['GN_API_KEY']}",
    "Content-Type": "application/json",
}

venues = requests.get("https://api.guestnetworks.com/api/venues", headers=headers)
print(venues.json())
TypeScript (MCP transport)
import { Client } from '@modelcontextprotocol/sdk/client/index.js';
import { StreamableHTTPClientTransport } from
  '@modelcontextprotocol/sdk/client/streamableHttp.js';

const client = new Client({ name: 'my-agent', version: '1.0' });

await client.connect(
  new StreamableHTTPClientTransport(
    new URL('https://api.guestnetworks.com/mcp'),
    {
      requestInit: {
        // Same Bearer token — one key works for REST and MCP
        headers: { 'Authorization': `Bearer ${process.env.GN_API_KEY}` },
      },
    },
  ),
);

const result = await client.callTool('get_occupancy', { venue_id: '<uuid>' });
console.log(JSON.parse(result.content[0].text));

3. Error responses

Authentication failures return a JSON error envelope with a machine-readable code field. Rate-limit responses include a Retry-After header.

401 — Missing or invalid key
// HTTP 401 Unauthorized
{
  "error": "Unauthorized",
  "code":  "UNAUTHORIZED"
}

// Causes:
// - Missing Authorization header
// - Header present but key not found in database
// - Key has been rotated
429 — Rate limit exceeded
// HTTP 429 Too Many Requests
// Headers include:
//   Retry-After: 15   (seconds until the window resets)

{
  "error": "Rate limit exceeded",
  "code":  "RATE_LIMITED"
}

// Back off for Retry-After seconds, then retry.
// The SDK (@guestnetworks/sdk) retries 429s automatically.

4. Per-plan limits

Rate limits are per-operator and enforced monthly. Ingest events over quota are dropped on Free; other plans charge overage. API calls and MCP queries reset on the billing cycle date.

PlanIngest eventsAPI callsMCP queriesMax venuesRetention
Free10,000 / mo500 / mo100 / mo17 days
Team100,000 / mo10,000 / mo1,000 / mo590 days
Business1,000,000 / mo100,000 / mo10,000 / moUnlimited365 days
EnterpriseUnlimitedUnlimitedUnlimitedUnlimited5 years

Request-level rate limits (ingest burst cap): POST /ingest is capped at 100 requests/min per operator across all plans. All other authenticated endpoints allow 1,000 requests/min.

Next steps