113 lines
2.5 KiB
Markdown
113 lines
2.5 KiB
Markdown
|
|
# @socialhose/api
|
||
|
|
|
||
|
|
TypeScript SDK for the Socialhose Public API.
|
||
|
|
|
||
|
|
## Install
|
||
|
|
|
||
|
|
```bash
|
||
|
|
npm install @socialhose/api
|
||
|
|
```
|
||
|
|
|
||
|
|
Node 18+ is required because the SDK uses the built-in `fetch`, `Response`, and `AbortSignal.timeout` APIs. You can pass a custom `fetch` implementation if needed.
|
||
|
|
|
||
|
|
## Quickstart
|
||
|
|
|
||
|
|
```ts
|
||
|
|
import { SocialhoseClient } from '@socialhose/api';
|
||
|
|
|
||
|
|
const socialhose = new SocialhoseClient({
|
||
|
|
apiKey: process.env.SOCIALHOSE_API_KEY!,
|
||
|
|
});
|
||
|
|
|
||
|
|
const mentions = await socialhose.getMentions({
|
||
|
|
content_search: 'hospital',
|
||
|
|
platforms: 'twitter',
|
||
|
|
ordering: '-published_at',
|
||
|
|
});
|
||
|
|
|
||
|
|
console.log(mentions.count, mentions.results[0]?.content);
|
||
|
|
```
|
||
|
|
|
||
|
|
## Configuration
|
||
|
|
|
||
|
|
```ts
|
||
|
|
const socialhose = new SocialhoseClient({
|
||
|
|
apiKey: process.env.SOCIALHOSE_API_KEY!,
|
||
|
|
baseUrl: 'https://socialhose.net/api/public/v1',
|
||
|
|
timeoutMs: 8_000,
|
||
|
|
retries: 3,
|
||
|
|
cacheTtlMs: 60_000,
|
||
|
|
});
|
||
|
|
```
|
||
|
|
|
||
|
|
The SDK sends `Authorization: Api-Key <key>` and a browser-like `User-Agent` by default. The user-agent is intentional: the current Socialhose API edge rejects some non-browser requests.
|
||
|
|
|
||
|
|
## Endpoints
|
||
|
|
|
||
|
|
- `getCampaigns()`
|
||
|
|
- `getCampaign(id)`
|
||
|
|
- `getOverview(filters)`
|
||
|
|
- `getTimeline(filters)`
|
||
|
|
- `getSentiment(filters)`
|
||
|
|
- `getShareOfVoice(filters)`
|
||
|
|
- `getPlatforms(filters)`
|
||
|
|
- `getTopKeywords(filters)`
|
||
|
|
- `getTrending(filters)`
|
||
|
|
- `getTopMentions(filters)`
|
||
|
|
- `getMentions(filters)`
|
||
|
|
- `getMailingLists()`
|
||
|
|
- `inviteMailingListMember(listId, invite)`
|
||
|
|
- `get(path, params)` for lower-level GET access
|
||
|
|
- `post(path, body)` for lower-level POST access
|
||
|
|
|
||
|
|
## Filtering examples
|
||
|
|
|
||
|
|
```ts
|
||
|
|
await socialhose.getOverview({
|
||
|
|
campaign_ids: 'campaign-id',
|
||
|
|
date_from: '2026-05-01',
|
||
|
|
date_to: '2026-05-29',
|
||
|
|
platforms: 'twitter,reddit',
|
||
|
|
sentiments: 'negative',
|
||
|
|
});
|
||
|
|
|
||
|
|
await socialhose.getTimeline({
|
||
|
|
campaign_ids: 'campaign-id',
|
||
|
|
interval: 'day',
|
||
|
|
});
|
||
|
|
```
|
||
|
|
|
||
|
|
## Next.js cache integration
|
||
|
|
|
||
|
|
Pass `revalidateSeconds` per request. In Next.js this is forwarded as `fetch(..., { next: { revalidate } })`; outside Next.js it is harmless.
|
||
|
|
|
||
|
|
```ts
|
||
|
|
await socialhose.getMentions({ content_search: 'ozempic' }, { revalidateSeconds: 3600 });
|
||
|
|
```
|
||
|
|
|
||
|
|
## Errors
|
||
|
|
|
||
|
|
Failed requests throw `SocialhoseError` with `status`, `path`, and response `body` when available.
|
||
|
|
|
||
|
|
```ts
|
||
|
|
import { SocialhoseError } from '@socialhose/api';
|
||
|
|
|
||
|
|
try {
|
||
|
|
await socialhose.getCampaign('missing');
|
||
|
|
} catch (error) {
|
||
|
|
if (error instanceof SocialhoseError) {
|
||
|
|
console.error(error.status, error.path, error.body);
|
||
|
|
}
|
||
|
|
}
|
||
|
|
```
|
||
|
|
|
||
|
|
## Publishing
|
||
|
|
|
||
|
|
```bash
|
||
|
|
pnpm test
|
||
|
|
pnpm typecheck
|
||
|
|
pnpm build
|
||
|
|
npm publish --access public --provenance
|
||
|
|
```
|
||
|
|
|