Skip to main content

API Reference

Authentication

SquirrelStack uses API keys passed via the X-Api-Key header, or personal access tokens (PATs) via Authorization: Bearer pat_…. Server-side integrations typically use the secret key. Personal tools (the CLI, the SquirrelStack Mac app) use a PAT scoped to a user — see CLI docs for details.

PAT requests need an account header

A PAT identifies a user, not an account. For endpoints that act on account data (dashboard, activity, errors, metrics summary), include X-Account-Slug: <slug> to pick which account to operate on. If your user belongs to exactly one account, the header is optional and that account is used by default. If your user belongs to multiple accounts and no slug is sent, the API returns 400 with a list of available slugs in available_accounts. Use GET /api/v1/me to discover what's available.

Site Key

Used for client-side tracking and chat widget endpoints. Safe to include in front-end code.

your_site_key

Secret Key

Used for server-side endpoints (subscriptions, custom metrics, deals). Keep this private.

your_secret_key

Sign in to see your actual API keys.

Base URL

https://squirrelstack.app/api/v1/

Request Format

All request and response bodies are JSON. Include these headers with every request:

Content-Type: application/json
X-Api-Key: your_api_key_here

Or with a personal access token:

Content-Type: application/json
Authorization: Bearer pat_xxx
X-Account-Slug: your_account_slug

Current User

GET /api/v1/me PAT

Returns the authenticated user and the accounts they belong to. Used by clients (CLI, Mac app) to populate an account picker. Does not require X-Account-Slug.

Success Response (200)

{
  "user": { "id": 1, "name": "Jane Doe", "email": "jane@example.com" },
  "accounts": [
    { "slug": "acme",  "name": "Acme Inc", "icon_url": "https://squirrelstack.app/rails/active_storage/..." },
    { "slug": "beta",  "name": "Beta Co",  "icon_url": null }
  ]
}

icon_url is an absolute URL to the account's square icon (a normalised PNG), or null when no icon has been uploaded — clients should render a monogram fallback. The URL changes whenever the icon changes, so it is safe to cache by URL.

Error Responses

Errors return the appropriate HTTP status code with a JSON body:

{
  "error": "A single error message"
}

// or for validation errors:
{
  "errors": [
    { "entity": "subscription", "index": 0, "message": "..." }
  ]
}
Status Meaning
401 Missing or invalid API key
403 Origin not allowed
404 Resource not found
422 Validation error
429 Rate limit exceeded
500 Internal server error

Rate Limiting

Some endpoints enforce per-IP rate limits. When exceeded, you'll receive a 429 Too Many Requests response.

Endpoint Limit
POST /tracking/visits 30 req/min
POST /tracking/events 60 req/min
GET /chat/config 60 req/min
POST /chat/conversations 5 req/min
GET /chat/.../messages 60 req/min
POST /chat/.../messages 20 req/min
POST /monitor/heartbeat/:token 60 req/min
GET /activity 30 req/min
GET /metrics_summary 30 req/min
GET /metrics/web 30 req/min
GET /metrics/web/visits 30 req/min
GET /metrics/web/events 30 req/min
/errors/* 30 req/min
POST /helpdesk/tickets 10 req/min
GET /helpdesk/tickets/:ticket_id/messages 60 req/min
GET /tickets 30 req/min
GET /tickets/:id 30 req/min
/crm/list_memberships 30 req/min
POST /projects/:project_id/notices 100 req/min