Help
Help
Utility Endpoints
A small group of utility routes used by the web app and supporting services. Most are public (no auth) and intended for narrow use cases.
Endpoint table
| Method | Path | Auth | Description |
|---|---|---|---|
| GET | /api/tags/trending | Session or Bearer | Most-used tags across public messages within a trailing time window. |
| GET | /api/tags/autocomplete | Session or Bearer | Tags on public messages matching a case-insensitive prefix. |
| GET | /api/location | Public | Resolve latitude/longitude to a US city, state, and timezone via NOAA. |
| GET | /api/weather | Public | US weather data from NOAA for a given lat/lon. Optional hourly and weekly series. |
| GET | /api/images/proxy | Public | Server-side image proxy for Instagram CDN images (CORS workaround). |
| POST | /api/analytics/ingest | Session optional | First-party page-view and action beacon used by the web app. |
| GET | /api/oauth/client-metadata | Public | Bluesky AT Protocol relying-party client metadata. Not for direct calls. |
| GET | /api/auth/linkedin/status | Public | Whether LinkedIn OAuth is configured on this deployment. |
| GET | /api/auth/twitter/status | Public | Whether X (Twitter) OAuth is configured on this deployment. |
| GET | /api/test-db | Public | Dev diagnostic that asserts the database is reachable. Do not depend on this in production. |
Tag discovery
Two authenticated read endpoints for surfacing and completing message tags. Both are scoped to public messages only (publiclyVisible = true) and require a session cookie or Authorization: Bearer <token>.
Trending tags
GET /api/tags/trending?window=week&limit=20
Authorization: Bearer 3f1c9e...<64 hex chars>...a8
| Query | Default | Notes |
|---|---|---|
limit | 20 | Number of tags to return. Clamped to a max of 100; a missing, non-numeric, or < 1 value falls back to the default. |
window | week | Trailing time window: day (1 day), week (7 days), or month (30 days). Any other value falls back to week. |
{
"tags": [
{ "tag": "release", "count": 42, "lastUsedAt": "2026-07-30T14:22:00.000Z" },
{ "tag": "dev", "count": 37, "lastUsedAt": "2026-07-31T09:05:00.000Z" }
]
}
Tags are ordered by count (descending), then by lastUsedAt (most recent first). count is the number of public messages using the tag within the window; lastUsedAt is an ISO-8601 timestamp of the most recent such message.
Tag autocomplete
GET /api/tags/autocomplete?q=re&limit=10
Authorization: Bearer 3f1c9e...<64 hex chars>...a8
| Query | Default | Notes |
|---|---|---|
q | required | Case-insensitive literal prefix to match. A single leading # is stripped. Returns 400 if empty after trimming. |
limit | 10 | Number of suggestions to return. Clamped to a max of 50; a missing, non-numeric, or < 1 value falls back to the default. |
{
"tags": [
{ "tag": "release", "count": 42 },
{ "tag": "react", "count": 18 }
]
}
Suggestions are ordered by count (descending), then alphabetically. Matching is a literal prefix (% and _ are not wildcards). An empty q returns 400 { "error": "Query parameter 'q' is required" }.
Geolocation
GET /api/location?latitude=47.6&longitude=-122.3
{
"city": "Seattle",
"state": "WA",
"country": "United States",
"coordinates": { "latitude": 47.6, "longitude": -122.3 },
"timezone": "America/Los_Angeles"
}
US coordinates only.
Weather
GET /api/weather?latitude=47.6&longitude=-122.3&extended=true
| Query | Default | Notes |
|---|---|---|
latitude, longitude | required | |
extended | false | Include hourly and weekly series. |
refresh | false | Bypass the server-side LRU cache (30 min per gridpoint). |
{
"location": "Seattle",
"temperature": 62,
"condition": "Partly Sunny",
"conditionIcon": "bx-cloud",
"high": 68, "low": 54,
"humidity": 71,
"windSpeed": 5,
"timeZone": "America/Los_Angeles",
"hourly": [ { "startTime": "...", "temperature": 62, "probabilityOfPrecipitation": 0, "shortForecast": "Partly Sunny" } ],
"weekly": [ { "name": "Tonight", "isDaytime": false, "temperature": 54, "shortForecast": "Mostly Cloudy", "icon": "..." } ]
}
Image proxy
GET /api/images/proxy?url=https://instagram.com/p/abc.jpg
Streams the bytes back with appropriate caching. On any failure (timeout, non-image content type, oversized response, network error) it responds with a placeholder SVG and the header X-Image-Status: placeholder; it does not return 4xx/5xx for image fetch failures.
Allowed hostnames: instagram.com, cdninstagram.com, fbcdn.net, and subdomains. Any other domain returns 403.
Analytics beacon
POST /api/analytics/ingest
Content-Type: application/json
{ "type": "page_view", "path": "/dashboard", "referrer": "https://google.com" }
For named actions:
{ "type": "action", "name": "post_created", "properties": { "channel": "web" } }
Always returns 204 No Content; invalid bodies are silently dropped. The server sets the interlinedlist_analytics_session cookie on first call (30-day lifetime by default).
Provider configuration probes
GET /api/auth/linkedin/status
GET /api/auth/twitter/status
Both respond with { "configured": boolean, "redirectUri": string | null }. Use these to decide whether to surface a LinkedIn/X sign-in button.
Bluesky AT Protocol metadata
GET /api/oauth/client-metadata returns the standard OAuth client-metadata JSON consumed by Bluesky's auth server during the OAuth handshake. The URL also serves as the BLUESKY_CLIENT_ID. Don't call this from your own code; it exists to make the OAuth flow work.
Related
- Authentication & OAuth: the OAuth flows these provider-status probes support.
- Messages: tag discovery powers tag autocomplete on the composer.
- API overview: base URL, authentication at a glance, and response conventions.
- API explorer: try utility endpoints live with the interactive Swagger console.