{"id":26910447,"url":"https://github.com/mackenly/fathom-api","last_synced_at":"2025-04-01T13:38:16.651Z","repository":{"id":281074848,"uuid":"944093435","full_name":"mackenly/fathom-api","owner":"mackenly","description":"Typescript wrapper around Fathom Analytic's API","archived":false,"fork":false,"pushed_at":"2025-03-07T22:07:14.000Z","size":260,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-03-27T22:51:24.483Z","etag":null,"topics":["fathom","fathom-analytics"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/@mackenly/fathom-api","language":"TypeScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"mit","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/mackenly.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null}},"created_at":"2025-03-06T19:19:10.000Z","updated_at":"2025-03-07T23:03:28.000Z","dependencies_parsed_at":"2025-03-06T21:39:32.192Z","dependency_job_id":null,"html_url":"https://github.com/mackenly/fathom-api","commit_stats":null,"previous_names":["mackenly/fathom-api"],"tags_count":6,"template":false,"template_full_name":null,"repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mackenly%2Ffathom-api","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mackenly%2Ffathom-api/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mackenly%2Ffathom-api/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/mackenly%2Ffathom-api/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/mackenly","download_url":"https://codeload.github.com/mackenly/fathom-api/tar.gz/refs/heads/main","host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":246648855,"owners_count":20811611,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2022-07-04T15:15:14.044Z","host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["fathom","fathom-analytics"],"created_at":"2025-04-01T13:38:15.675Z","updated_at":"2025-04-01T13:38:16.638Z","avatar_url":"https://github.com/mackenly.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Fathom Analytics API SDK\n\nA fully-typed unofficial TypeScript SDK for interacting with the [Fathom Analytics API](https://usefathom.com/api). Works in any JavaScript runtime environment that supports the Fetch API, including browsers, Node.js (v18+), Bun, Deno, Cloudflare Workers, and more.\n\n## Features\n\n- 🔒 Full TypeScript support with accurate type definitions\n- 🚀 Support for all Fathom Analytics API endpoints (as of writing)\n- 📊 Detailed response types for all API resources\n- 🔄 Promise-based API with async/await support\n- 📈 Smart pagination for listing resources\n- 🔍 Comprehensive methods for sites, events, reports, and more\n- ⚡ Works in any JavaScript runtime with Fetch API support\n- 🔮 Full support for current API capabilities and versioning for future proofing\n\n## Installation\nUse your favorite package manager and registry ([npm](https://www.npmjs.com/package/@mackenly/fathom-api), [jsr](https://jsr.io/@mackenly/fathom-api), and [GitHub Packages](https://github.com/users/mackenly/packages/npm/package/fathom-api)) to install the package:\n```bash\nnpm install @mackenly/fathom-api\n```\n```bash\nyarn add @mackenly/fathom-api\n```\n```bash\npnpm add @mackenly/fathom-api\n```\n```bash\ndeno add jsr:@mackenly/fathom-api\n```\n```typescript\nimport * as fathom_api from \"jsr:@mackenly/fathom-api\";\n```\n```bash\nbun add @mackenly/fathom-api\n```\n\n\n## Quick Start\n[Get an API token from your Fathom Analytics account settings](https://app.usefathom.com/api) and use it to create a new client.\n\n\u003e [!WARNING]  \n\u003e Use permissions to restrict the API token to only the necessary operations (ex: `Admin`, `All sites (read only)`, `Site specific`)\n\n```typescript\nimport FathomApi from '@mackenly/fathom-api';\n\n// Create a new client with your API token\nconst fathom = new FathomApi({\n  token: 'your-api-token',\n  // Optional parameters\n  // version: 'v1',\n  // baseUrl: 'https://api.usefathom.com'\n});\n\n// Example: Get account information\nasync function getAccountInfo() {\n  try {\n    const account = await fathom.api.account.get();\n    console.log('Account:', account);\n  } catch (error) {\n    if (error instanceof FathomApiError) {\n      console.error('API Error:', error.message);\n    } else {\n      console.error('Error:', error);\n    }\n  }\n}\n\ngetAccountInfo();\n```\n\n## Usage Examples\n\n### Managing Sites\n\n```typescript\n// List all sites\nconst sites = await fathom.api.getAllSites();\n\n// Get a specific site\nconst site = await fathom.api.sites.get('SITEID');\n\n// Create a new site\nconst newSite = await fathom.api.sites.create({\n  name: 'My New Website'\n});\n\n// Update a site\nconst updatedSite = await fathom.api.sites.update('SITEID', {\n  name: 'Updated Website Name',\n  sharing: 'private',\n  share_password: 'password123'\n});\n\n// Wipe site data\nconst wipedSite = await fathom.api.sites.wipe('SITEID');\n\n// Delete a site\nconst deletedSite = await fathom.api.sites.delete('SITEID');\n```\n\n### Working with Events\n\n```typescript\n// List all events for a site\nconst events = await fathom.api.getAllEvents('SITEID');\n\n// Get a specific event\nconst event = await fathom.api.events('SITEID').get('EVENT_ID');\n\n// Create a new event\nconst newEvent = await fathom.api.events('SITEID').create({\n  name: 'Newsletter Signup'\n});\n\n// Update an event\nconst updatedEvent = await fathom.api.events('SITEID').update('EVENT_ID', {\n  name: 'Updated Event Name'\n});\n\n// Wipe event data\nconst wipedEvent = await fathom.api.events('SITEID').wipe('EVENT_ID');\n\n// Delete an event\nconst deletedEvent = await fathom.api.events('SITEID').delete('EVENT_ID');\n```\n\n### Generating Reports\n\n```typescript\n// Get aggregation report for pageviews\nconst pageviewReport = await fathom.api.reports.aggregation({\n  entity: 'pageview',\n  entity_id: 'SITEID',\n  aggregates: 'visits,uniques,pageviews',\n  date_grouping: 'day',\n  field_grouping: 'pathname',\n  date_from: '2022-01-01',\n  date_to: '2022-01-31',\n  filters: [\n    {\n      property: 'pathname',\n      operator: 'is',\n      value: '/blog'\n    }\n  ]\n});\n\n// Get aggregation report for events\nconst eventReport = await fathom.api.reports.aggregation({\n  entity: 'event',\n  entity_id: 'EVENT_ID',\n  aggregates: 'conversions,unique_conversions',\n  date_grouping: 'month'\n});\n\n// Get current visitors\nconst currentVisitors = await fathom.api.reports.currentVisitors({\n  site_id: 'SITEID',\n  detailed: true\n});\n```\n\n### Using Different API Versions\n\nThis SDK is designed to support potential future API versions. The default version and, as of writing, the only version is v1, but you can specify a different version when creating the client or accessing the API:\n\n```typescript\n// Specify version at initialization\nconst fathom = new FathomApi({\n  token: 'your-api-token',\n  version: 'v1'\n});\n\n// Or access a specific version after initialization\nconst v1 = fathom.version('v1');\n```\n\n## API Reference\n\n### Client Initialization\n\n```typescript\nnew FathomApi(options: {\n  token: string;          // Your Fathom API token\n  version?: 'v1';         // API version to use (default: 'v1')\n  baseUrl?: string;       // API base URL (default: 'https://api.usefathom.com')\n})\n```\n\n### Resources\n\n- `.api.account` - Account operations\n- `.api.sites` - Site operations\n- `.api.events(siteId)` - Event operations for a specific site\n- `.api.reports` - Report generation\n- `.api.*` - Variety of convenience methods for common operations\n\n## Error Handling\n\nThe SDK throws `FathomApiError` instances for API errors. These include an `error` property with the error message from the API and a `status` property with the HTTP status code:\n\n```typescript\nimport { FathomApi, FathomApiError } from '@mackenly/fathom-api';\n\ntry {\n  const result = await fathom.api.sites.get('non-existent-site');\n} catch (error) {\n  if (error instanceof FathomApiError) {\n    console.error(`API Error (${error.status}):`, error.error);\n  } else {\n    console.error('Unexpected error:', error);\n  }\n}\n```\n\n## Pagination\n\nList operations support pagination parameters:\n\n```typescript\nconst firstTwentySites = await fathom.api.sites.list({ limit: 20 });\n```\nOr to get all sites with automatic pagination:\n\n```typescript\nconst allSites = await fathom.api.getAllSites();\n```\n\n## Proxy Example\nIf you're using this browser in frontend code or other applications where you might want to not include your API key, you can create a server-side request proxy to forward requests to the Fathom API, validate incoming API keys, and add your Fathom API key for the actual request to Fathom. Here's an example:\n\nIn your client side code:\n```typescript\nconst fathom = new FathomApi({\n  token: 'temp_token',\n  baseUrl: 'https://your-proxy-server.com'\n});\n```\n\nA Cloudflare Worker:\n```typescript\nexport default {\n  async fetch(request) {\n    // Only allow GET requests for this example\n    if (request.method !== 'GET') {\n      return new Response('Method not allowed', { status: 405 });\n    }\n\n    const url = new URL(request.url);\n    const targetUrl = new URL(url.pathname + url.search, 'https://api.usefathom.com');\n    const newHeaders = new Headers(request.headers);\n    let authHeader = newHeaders.get('Authorization');\n\n    // Modify this to validate incoming API keys (perhaps from a database)\n    if (authHeader \u0026\u0026 authHeader.includes('temp_token')) {\n      authHeader = authHeader.replace('temp_token', 'real_token');\n      newHeaders.set('Authorization', authHeader);\n    }\n\n    return await fetch(targetUrl.toString(), {\n      method: 'GET',\n      headers: newHeaders,\n    });\n  }\n}\n```\n\n## Compatibility\n\nThis library is tested for compatibility with:\n- Node.js 18+\n- Modern browsers (Chrome, Firefox, Safari, Edge)\n- Cloudflare Workers\n- Bun\n- Deno\n\n\u003e [!WARNING]  \n\u003e If running in a browser environment or anywhere that users could access the API token, it is recommended to use a server-side proxy to keep the token secure rather than exposing it directly in client-side code.\n\nThe library uses standard Web APIs and modern JavaScript features that are widely supported across JavaScript environments.\n\n## Contributing\n\nContributions are welcome! Please feel free to submit a Pull Request.\n\n## License\n\n[MIT](./LICENSE)\n\nThis project is not affiliated with, part of, or endorsed by Fathom Analytics or Conva Ventures Inc. For Fathom issues or support requests not related to this package, please contact the Fathom team directly. For enterprise support for this package, please contact [Tricities Media Group](https://tricitiesmediagroup.com).","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmackenly%2Ffathom-api","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fmackenly%2Ffathom-api","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fmackenly%2Ffathom-api/lists"}