docs: expand JavaScript SDK documentation
This commit is contained in:
@@ -0,0 +1,366 @@
|
||||
# API Reference
|
||||
|
||||
Public API reference for `@socialhose/api`, the TypeScript SDK for the Socialhose Public API.
|
||||
|
||||
The SDK is intended for server-side JavaScript/TypeScript. It authenticates requests with an API key, wraps Socialhose REST endpoints, normalizes common response shapes, retries transient failures, applies request timeouts, and caches GET responses.
|
||||
|
||||
## Package exports
|
||||
|
||||
```ts
|
||||
import {
|
||||
SocialhoseClient,
|
||||
createSocialhoseClient,
|
||||
SocialhoseError,
|
||||
MemoryCache,
|
||||
NoopCache,
|
||||
type Cache,
|
||||
type SocialhoseClientOptions,
|
||||
type RequestOptions,
|
||||
type AnalyticsFilters,
|
||||
type MentionFilters,
|
||||
} from '@socialhose/api';
|
||||
```
|
||||
|
||||
## Authentication
|
||||
|
||||
Every request sends:
|
||||
|
||||
- `Authorization: Api-Key <apiKey>`
|
||||
- `Accept: application/json`
|
||||
- a browser-like `User-Agent` by default
|
||||
- `Content-Type: application/json` for `POST`
|
||||
|
||||
Do not use this SDK directly in browser code. Keep `SOCIALHOSE_API_KEY` on the server.
|
||||
|
||||
## `SocialhoseClientOptions`
|
||||
|
||||
Configuration object for `new SocialhoseClient(options)` and `createSocialhoseClient(options)`.
|
||||
|
||||
- `apiKey: string` — Socialhose API key. Required; empty strings fail on first request.
|
||||
- `baseUrl?: string` — API root. Default: `https://socialhose.net/api/public/v1`.
|
||||
- `userAgent?: string` — request user-agent. Default is Chrome-like because the API edge may reject generic Node clients.
|
||||
- `fetch?: typeof fetch` — custom fetch implementation for tests, instrumentation, or runtimes without global fetch.
|
||||
- `timeoutMs?: number` — per-attempt timeout. Default: `8000`.
|
||||
- `retries?: number` — retry count after the first attempt. Default: `3`.
|
||||
- `retryDelayMs?: (attempt: number) => number` — retry backoff function. Default: exponential backoff with jitter.
|
||||
- `cacheTtlMs?: number` — default GET cache TTL in milliseconds. Default: `60000`; set `0` to disable the built-in memory cache.
|
||||
- `cache?: Cache` — custom cache implementation. If supplied, it replaces the internal cache.
|
||||
- `defaultHeaders?: Record<string, string>` — extra headers sent with every request.
|
||||
|
||||
## `RequestOptions`
|
||||
|
||||
Per-request options.
|
||||
|
||||
- `revalidateSeconds?: number` — override cache TTL for this call, in seconds. Passed only to `Cache.set`; not sent to the API.
|
||||
- `signal?: AbortSignal` — caller abort signal combined with the SDK timeout.
|
||||
- `headers?: Record<string, string>` — request-specific headers.
|
||||
|
||||
## `new SocialhoseClient(options)`
|
||||
|
||||
Creates an authenticated API client.
|
||||
|
||||
```ts
|
||||
const socialhose = new SocialhoseClient({
|
||||
apiKey: process.env.SOCIALHOSE_API_KEY!,
|
||||
timeoutMs: 8_000,
|
||||
retries: 3,
|
||||
cacheTtlMs: 60_000,
|
||||
});
|
||||
```
|
||||
|
||||
## `createSocialhoseClient(options)`
|
||||
|
||||
Factory wrapper around the constructor.
|
||||
|
||||
```ts
|
||||
const socialhose = createSocialhoseClient({ apiKey });
|
||||
```
|
||||
|
||||
Returns `SocialhoseClient`.
|
||||
|
||||
## Low-level HTTP methods
|
||||
|
||||
### `client.get<T>(path, params?, options?)`
|
||||
|
||||
Performs an authenticated cached GET request.
|
||||
|
||||
- `path: string` — endpoint path, with or without leading slash.
|
||||
- `params?: QueryParams` — query parameters. `undefined`, `null`, and `''` values are omitted.
|
||||
- `options?: RequestOptions` — cache TTL, abort signal, and extra headers.
|
||||
|
||||
Returns `Promise<T>`.
|
||||
|
||||
Behavior:
|
||||
|
||||
- Builds the URL from `baseUrl`, `path`, and `params`.
|
||||
- Uses the full URL as the cache key.
|
||||
- Retries network errors, timeouts, `429`, and `5xx` responses.
|
||||
- Throws `SocialhoseError` for non-OK responses after retries.
|
||||
|
||||
### `client.post<T>(path, body, options?)`
|
||||
|
||||
Performs an authenticated JSON POST request.
|
||||
|
||||
- `path: string` — endpoint path.
|
||||
- `body: unknown` — JSON-serialized request body.
|
||||
- `options?: RequestOptions` — abort signal and extra headers.
|
||||
|
||||
Returns `Promise<{ status: number; data: T | null }>`.
|
||||
|
||||
Behavior:
|
||||
|
||||
- Never uses the GET cache.
|
||||
- Sends `Content-Type: application/json`.
|
||||
- Returns the HTTP status so higher-level methods can normalize status-specific outcomes.
|
||||
- Lets POST `409` responses through for conflict normalization.
|
||||
|
||||
## Campaign methods
|
||||
|
||||
### `client.getCampaigns(options?)`
|
||||
|
||||
Fetches first-page campaigns.
|
||||
|
||||
Endpoint: `GET /campaigns/?page=1`
|
||||
|
||||
Returns `Promise<Campaign[]>`.
|
||||
|
||||
Use it to list accessible campaigns or populate campaign selectors. The helper reads page 1 only; use `get<Paginated<Campaign>>()` for manual pagination.
|
||||
|
||||
### `client.getCampaign(id, options?)`
|
||||
|
||||
Fetches one campaign by ID.
|
||||
|
||||
Endpoint: `GET /campaigns/{id}/`
|
||||
|
||||
Returns `Promise<Campaign>`.
|
||||
|
||||
Throws `SocialhoseError` when the campaign is missing or inaccessible.
|
||||
|
||||
### `client.getCampaignIdByMatch(match, options?)`
|
||||
|
||||
Returns the first campaign ID whose name contains `match`, case-insensitively.
|
||||
|
||||
Returns `Promise<string | undefined>`.
|
||||
|
||||
If campaign fetching fails or no campaign matches, returns `undefined`. Use exact IDs when names may collide.
|
||||
|
||||
## Analytics filters
|
||||
|
||||
`AnalyticsFilters` are passed through as query params:
|
||||
|
||||
- `campaign_ids?: string` — one ID or comma-separated IDs.
|
||||
- `date_from?: string` — lower date bound, commonly `YYYY-MM-DD`.
|
||||
- `date_to?: string` — upper date bound, commonly `YYYY-MM-DD`.
|
||||
- `platforms?: string` — platform or comma-separated platforms.
|
||||
- `sentiments?: string` — sentiment or comma-separated sentiments.
|
||||
|
||||
## Analytics methods
|
||||
|
||||
### `client.getOverview(filters?, options?)`
|
||||
|
||||
Endpoint: `GET /analytics/overview/`
|
||||
|
||||
Returns `Promise<Overview>` with total mentions, authors, estimated reach, sentiment distribution, platform breakdown, engagement, and growth metrics.
|
||||
|
||||
The SDK coerces `total_mentions` and `total_authors` to numbers because some API responses may return numeric strings.
|
||||
|
||||
### `client.getTimeline(filters?, options?)`
|
||||
|
||||
Endpoint: `GET /analytics/timeline/`
|
||||
|
||||
Filters include `interval?: 'day' | 'week' | 'month'`, defaulting to `day`.
|
||||
|
||||
Returns `Promise<TimelinePoint[]>`. If the API response lacks `series`, returns `[]`.
|
||||
|
||||
### `client.getSentiment(filters?, options?)`
|
||||
|
||||
Endpoint: `GET /analytics/sentiment/`
|
||||
|
||||
Returns `Promise<{ distribution: SentimentSplit; by_platform: Record<string, SentimentSplit> }>`.
|
||||
|
||||
### `client.getShareOfVoice(filters?, options?)`
|
||||
|
||||
Endpoint: `GET /analytics/share-of-voice/`
|
||||
|
||||
Returns `Promise<{ total_mentions: number; campaigns: ShareOfVoiceItem[] }>`.
|
||||
|
||||
Each campaign row includes mention count, share percentage, engagement, and sentiment.
|
||||
|
||||
### `client.getPlatforms(filters?, options?)`
|
||||
|
||||
Endpoint: `GET /analytics/platforms/`
|
||||
|
||||
Returns `Promise<PlatformStat[]>`. If the API response lacks `platforms`, returns `[]`.
|
||||
|
||||
### `client.getTopKeywords(filters?, options?)`
|
||||
|
||||
Endpoint: `GET /analytics/top-keywords/`
|
||||
|
||||
Filters include `limit?: number`, defaulting to `12`.
|
||||
|
||||
Returns `Promise<KeywordStat[]>`. If the API response lacks `keywords`, returns `[]`.
|
||||
|
||||
### `client.getTrending(filters?, options?)`
|
||||
|
||||
Endpoint: `GET /analytics/trending/`
|
||||
|
||||
Filters include `limit?: number`, defaulting to `8`.
|
||||
|
||||
Returns `Promise<TrendingItem[]>`. If the API response lacks `trending`, returns `[]`.
|
||||
|
||||
### `client.getTopMentions(filters?, options?)`
|
||||
|
||||
Endpoint: `GET /analytics/top-mentions/`
|
||||
|
||||
Filters include `limit?: number`, defaulting to `6`.
|
||||
|
||||
Returns `Promise<TopMention[]>`. If the API response lacks `mentions`, returns `[]`.
|
||||
|
||||
## Mention methods
|
||||
|
||||
### `client.getMentions(filters?, optionsOrRevalidate?)`
|
||||
|
||||
Endpoint: `GET /mentions/`
|
||||
|
||||
Returns `Promise<Paginated<Mention>>`.
|
||||
|
||||
`MentionFilters` include all `AnalyticsFilters` plus:
|
||||
|
||||
- `page?: number` — page number, defaulting to `1`.
|
||||
- `content_search?: string` — text search term.
|
||||
- `ordering?: string` — sort key, such as `-published_at` or `-engagement_count`.
|
||||
|
||||
The second argument may be `RequestOptions` or the legacy shorthand `number` for `revalidateSeconds`.
|
||||
|
||||
## Mailing-list methods
|
||||
|
||||
### `client.getMailingLists(options?)`
|
||||
|
||||
Endpoint: `GET /mailing-lists/?page=1`
|
||||
|
||||
Returns `Promise<MailingList[]>` from the first page.
|
||||
|
||||
### `client.inviteMailingListMember(listId, invite, options?)`
|
||||
|
||||
Endpoint: `POST /mailing-lists/{listId}/members/`
|
||||
|
||||
`invite` fields:
|
||||
|
||||
- `email: string`
|
||||
- `first_name?: string`
|
||||
- `last_name?: string`
|
||||
- `invitation_message?: string`
|
||||
|
||||
Returns `Promise<InviteResult>`:
|
||||
|
||||
- `{ outcome: 'invited', invitation }` for `201` plus `status: 'invited'`.
|
||||
- `{ outcome: 'already', detail }` for `409` conflicts.
|
||||
- `{ outcome: 'error', detail }` for unexpected successful/conflict response shapes.
|
||||
|
||||
Other non-OK statuses throw `SocialhoseError`.
|
||||
|
||||
## Entity analytics methods
|
||||
|
||||
Entity analytics are SDK-composed views built on `/mentions/` with `content_search`. They provide term/person/org/topic analytics when native analytics endpoints are campaign-scoped.
|
||||
|
||||
### `client.getEntityBrief(term, campaignId?, options?)`
|
||||
|
||||
Runs one mention search ordered by engagement.
|
||||
|
||||
Returns `Promise<EntityBrief>`:
|
||||
|
||||
- `term` — requested search term.
|
||||
- `total` — exact API count.
|
||||
- `exact` — true when the sample covers the full population.
|
||||
- `sentiment` — sample-derived sentiment split.
|
||||
- `platformMix` — sample-derived platform counts.
|
||||
- `sample` — first page ordered by engagement.
|
||||
|
||||
`total` is exact. Sentiment and platform mix are exact only when `exact` is true.
|
||||
|
||||
### `client.getEntityStats(term, campaignId?, options?)`
|
||||
|
||||
Builds a richer dashboard for one term.
|
||||
|
||||
Returns `Promise<EntityStats>` with `EntityBrief` fields plus:
|
||||
|
||||
- `recent` — newest mentions.
|
||||
- `recent7d` — latest seven-day count from the sparkline.
|
||||
- `prev7d` — previous seven-day count.
|
||||
- `momentumPct` — seven-day percentage change, or `null` if not computable.
|
||||
- `sparkline` — daily counts for the last 14 days when date faceting is trustworthy.
|
||||
|
||||
Failure model:
|
||||
|
||||
- The initial brief must succeed.
|
||||
- Follow-up subrequests are best-effort.
|
||||
- Exact facets are used only when reconciliation checks pass; otherwise sample-derived values are retained.
|
||||
|
||||
### `client.getEntityBriefs(terms, campaignId?, concurrency?, options?)`
|
||||
|
||||
Fetches many entity briefs with bounded concurrency.
|
||||
|
||||
Returns `Promise<Map<string, EntityBrief>>`.
|
||||
|
||||
Failed terms are omitted from the map. Default concurrency is `20`; reduce it under rate limits.
|
||||
|
||||
## Cache API
|
||||
|
||||
### `Cache`
|
||||
|
||||
```ts
|
||||
interface Cache {
|
||||
get(key: string): Promise<unknown | undefined>;
|
||||
set(key: string, value: unknown, ttlMs: number): Promise<void>;
|
||||
delete(key: string): Promise<void>;
|
||||
}
|
||||
```
|
||||
|
||||
The key is the full GET URL. `get()` returns `undefined` on cache miss. `ttlMs` is in milliseconds.
|
||||
|
||||
### `MemoryCache`
|
||||
|
||||
In-memory `Map` cache with per-entry TTL. Good for tests, scripts, and single-process services. Not enough for distributed rate-limit protection.
|
||||
|
||||
### `NoopCache`
|
||||
|
||||
Cache implementation that never stores values. Use it to force fresh data or disable caching explicitly.
|
||||
|
||||
### `client.clearCache()`
|
||||
|
||||
Deletes cache keys used by the current client instance. It is not a global purge for shared cache backends.
|
||||
|
||||
## `SocialhoseError`
|
||||
|
||||
Structured request failure.
|
||||
|
||||
Fields:
|
||||
|
||||
- `name: 'SocialhoseError'`
|
||||
- `status?: number`
|
||||
- `path: string`
|
||||
- `body?: string`
|
||||
- `cause?: unknown`
|
||||
|
||||
Thrown after retry exhaustion or unsupported non-OK HTTP responses.
|
||||
|
||||
## Core data types
|
||||
|
||||
- `Sentiment` — `'positive' | 'negative' | 'neutral'`.
|
||||
- `SentimentSplit` — `{ positive: number; negative: number; neutral: number }`.
|
||||
- `Paginated<T>` — `{ count, next, previous, results }`.
|
||||
- `Campaign` — campaign metadata.
|
||||
- `Overview` — aggregate analytics.
|
||||
- `TimelinePoint` — one time-series bucket.
|
||||
- `ShareOfVoiceItem` — campaign comparison row.
|
||||
- `PlatformStat` — platform count and engagement.
|
||||
- `KeywordStat` — keyword count and sentiment.
|
||||
- `TrendingItem` — keyword momentum.
|
||||
- `TopMention` — compact high-impact mention.
|
||||
- `Mention` — full mention record with content, engagement, metadata, and author profile.
|
||||
- `MailingList` — mailing-list metadata.
|
||||
- `MailingListInvitation` — mailing-list invitation state.
|
||||
- `InviteResult` — normalized invite result.
|
||||
- `PlatformShare` — entity analytics platform count.
|
||||
- `EntityBrief` — compact term analytics.
|
||||
- `EntityStats` — full term dashboard.
|
||||
Reference in New Issue
Block a user