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.
gn_live_ followed by 28 random characters. Example: gn_live_sk_xxxxxxxxxxxxxxxxxxxxxxxx. Store it in an environment variable — never hardcode it in source control.# 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 https://api.guestnetworks.com/api/venues \ -H "Authorization: Bearer $GN_API_KEY"
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();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())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.
// HTTP 401 Unauthorized
{
"error": "Unauthorized",
"code": "UNAUTHORIZED"
}
// Causes:
// - Missing Authorization header
// - Header present but key not found in database
// - Key has been rotated// 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.
| Plan | Ingest events | API calls | MCP queries | Max venues | Retention |
|---|---|---|---|---|---|
| Free | 10,000 / mo | 500 / mo | 100 / mo | 1 | 7 days |
| Team | 100,000 / mo | 10,000 / mo | 1,000 / mo | 5 | 90 days |
| Business | 1,000,000 / mo | 100,000 / mo | 10,000 / mo | Unlimited | 365 days |
| Enterprise | Unlimited | Unlimited | Unlimited | Unlimited | 5 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.