Authentication
API keys, token-based auth, rate limits, and CSRF protection.
IonHour supports two authentication methods: API keys for programmatic access and OAuth tokens for interactive sessions. Most integrations should use API keys.
API Keys
API keys are the recommended way to authenticate with the IonHour API from scripts, CI/CD pipelines, and third-party integrations. Each key is scoped to a single workspace.
Creating an API Key
- Navigate to Settings > API Keys in your workspace.
- Click Create API Key.
- Enter a name to identify the key's purpose.
- Copy the key immediately — it will not be shown again.
API keys follow the format ionh_ followed by 32 hex characters (37 characters total).
Using an API Key
Pass the key in the Authorization header:
curl -H "Authorization: Bearer ionh_your_api_key_here" \
https://app.failsignal.com/api/checks
Key Management
| Action | Description |
|---|---|
| Create | Generate a new key. Full key shown once. |
| List | View all keys in the workspace. Only the prefix is displayed. |
| Rotate | Generate a new key for an existing record. The old key is invalidated. |
| Revoke | Permanently delete a key. |
Security
- Keys are stored as SHA-256 hashes — IonHour never stores the plaintext key.
- Only the first 12 characters (prefix) are stored for identification.
- Each key tracks a
lastUsedAttimestamp for auditing. - Keys can be disabled without deleting them.
- Treat API keys like passwords — don't commit them to source control.
OAuth Tokens (Web and Mobile)
Interactive applications (like the IonHour dashboard) use OAuth 2.0 with Keycloak as the identity provider. This is primarily for building custom UIs — most API integrations should use API keys instead.
Web Flow
- Get login URL:
GET /api/auth/login-urlreturns a Keycloak authorization URL. - User authenticates: User is redirected to Keycloak, signs in, and is redirected back with an authorization code.
- Exchange code:
POST /api/auth/tokenexchanges the code for access and refresh tokens. - Use tokens: Access token is set as an HttpOnly cookie and sent automatically with requests.
- Refresh:
POST /api/auth/refreshrenews the access token using the refresh token.
Mobile Flow
Mobile apps use PKCE (Proof Key for Code Exchange) for added security:
POST /api/auth/mobile/login-url— returns auth URL with PKCE challenge.POST /api/auth/mobile/token— exchanges code + verifier for tokens (returned in response body, not cookies).POST /api/auth/mobile/refresh— refreshes tokens (accepts refresh token in request body).POST /api/auth/mobile/logout— revokes tokens.
CSRF Protection
State-changing requests (POST, PUT, PATCH, DELETE) from web clients require a CSRF token:
- A
csrf_tokencookie is set on login/refresh (JavaScript-accessible). - Include the token in the
X-CSRF-Tokenheader for all state-changing requests. - GET, HEAD, and OPTIONS requests are exempt.
Public Endpoints
These endpoints require no authentication:
| Endpoint | Purpose |
|---|---|
GET /api/signals/ping/:token | Send a heartbeat (GET) |
POST /api/signals/ping/:token | Send a heartbeat with payload (POST) |
GET /api/public/status/:slug | View a public status page |
GET /api/public/status/:slug/feed.rss | Status page RSS feed |
GET /api/public/status/:slug/badge.svg | Status badge |
GET /api/checks/:id/badge | Check status badge |
Rate Limits
IonHour enforces rate limits to protect the API from abuse. Limits are per client IP address.
Default Limit
100 requests per 60 seconds for all authenticated endpoints.
Auth Endpoints
| Endpoint | Limit |
|---|---|
GET /api/auth/login-url | 5 per 60s |
POST /api/auth/token | 10 per 60s |
POST /api/auth/refresh | 10 per 60s |
POST /api/auth/logout | 10 per 60s |
Public Status Page Endpoints
| Endpoint | Limit |
|---|---|
| Status page data, uptime, history | 30 per 60s |
| Password verification | 5 per 5 minutes |
| Subscription | 5 per 60s |
| RSS/Atom feeds | 10 per 60s |
Rate Limit Response
When the limit is exceeded, the API returns:
HTTP/1.1 429 Too Many Requests
Wait for the rate limit window to reset before retrying.
Workspace Scoping
All authenticated requests are scoped to a workspace. The workspace is determined by:
- API keys: The workspace the key was created in.
- OAuth tokens: The workspace selected by the user in the dashboard.
Data from one workspace is never accessible from another, even for the same user. This is enforced at the API level — you cannot query resources across workspaces in a single request.