{"id":26366415,"url":"https://github.com/rutbergphilip/blocket.js","last_synced_at":"2026-02-01T16:01:34.916Z","repository":{"id":279054961,"uuid":"937591835","full_name":"rutbergphilip/blocket.js","owner":"rutbergphilip","description":"A user-friendly wrapper for blocket.se's unofficial api","archived":false,"fork":false,"pushed_at":"2025-09-15T20:44:13.000Z","size":56,"stargazers_count":4,"open_issues_count":0,"forks_count":0,"subscribers_count":1,"default_branch":"main","last_synced_at":"2025-11-18T12:11:58.031Z","etag":null,"topics":["api-wrapper","blocket","blocketse","library"],"latest_commit_sha":null,"homepage":"https://www.npmjs.com/package/blocket.js","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/rutbergphilip.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,"zenodo":null,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2025-02-23T12:51:41.000Z","updated_at":"2025-09-15T20:44:08.000Z","dependencies_parsed_at":"2025-02-23T14:18:29.313Z","dependency_job_id":"ceb0bb70-6142-4062-aed9-0a14d3e79730","html_url":"https://github.com/rutbergphilip/blocket.js","commit_stats":null,"previous_names":["rutbergphilip/blocket.js"],"tags_count":21,"template":false,"template_full_name":null,"purl":"pkg:github/rutbergphilip/blocket.js","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rutbergphilip%2Fblocket.js","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rutbergphilip%2Fblocket.js/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rutbergphilip%2Fblocket.js/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rutbergphilip%2Fblocket.js/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/rutbergphilip","download_url":"https://codeload.github.com/rutbergphilip/blocket.js/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/rutbergphilip%2Fblocket.js/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":28981893,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-01T15:35:50.179Z","status":"ssl_error","status_checked_at":"2026-02-01T15:35:38.075Z","response_time":56,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"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":["api-wrapper","blocket","blocketse","library"],"created_at":"2025-03-16T20:16:48.407Z","updated_at":"2026-02-01T16:01:34.910Z","avatar_url":"https://github.com/rutbergphilip.png","language":"TypeScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"# blocket.js\n\nA lightweight TypeScript/JavaScript client for searching ads on [Blocket.se](https://blocket.se) - Sweden's largest marketplace.\n\n[![npm version](https://img.shields.io/npm/v/blocket.js)](https://www.npmjs.com/package/blocket.js)\n[![npm downloads](https://img.shields.io/npm/dm/blocket.js)](https://www.npmjs.com/package/blocket.js)\n[![build status](https://img.shields.io/github/actions/workflow/status/rutbergphilip/blocket.js/publish.yml)](https://github.com/rutbergphilip/blocket.js/actions)\n[![license](https://img.shields.io/npm/l/blocket.js)](https://github.com/rutbergphilip/blocket.js/blob/main/LICENSE)\n\n## Features\n\n- **Simple API** - Just import and search, no setup required\n- **Automatic Pagination** - Fetches all results across multiple pages automatically\n- **TypeScript Support** - Fully typed interfaces for all responses\n- **Zero Configuration** - Works out of the box with sensible defaults\n- **Lightweight** - Minimal dependencies\n\n## Installation\n\n```bash\nnpm install blocket.js\n```\n\n```bash\nyarn add blocket.js\n```\n\n```bash\npnpm add blocket.js\n```\n\n## Quick Start\n\n```typescript\nimport client from 'blocket.js';\n\n// Search for items\nconst ads = await client.find({ query: 'iPhone 15' });\n\nconsole.log(`Found ${ads.length} ads`);\nads.forEach(ad =\u003e {\n  console.log(`${ad.heading} - ${ad.price.amount} ${ad.price.currency_code}`);\n});\n```\n\n## API Reference\n\n### `client.find(query, options?)`\n\nSearch for ads on Blocket. Automatically handles pagination to return all matching results.\n\n```typescript\nimport { BlocketLocations, BlocketCategories } from 'blocket.js';\n\nconst ads = await client.find({\n  query: 'macbook pro',                           // Required: search term\n  limit: 50,                                       // Results per page (default: 20, max: 60)\n  sort: 'PRICE_ASC',                              // Sort order\n  location: BlocketLocations.STOCKHOLM,           // Filter by region\n  category: BlocketCategories.ELEKTRONIK_OCH_VITVAROR, // Filter by category\n});\n```\n\n#### Query Options\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `query` | `string` | *required* | Search term |\n| `limit` | `number` | `20` | Results per page (max 60) |\n| `sort` | `string` | `'RELEVANCE'` | `'RELEVANCE'`, `'PRICE_ASC'`, `'PRICE_DESC'`, `'PUBLISHED_ASC'`, `'PUBLISHED_DESC'` |\n| `location` | `string \\| string[]` | - | Filter by region (use `BlocketLocations` constants) |\n| `category` | `string` | - | Filter by main category (use `BlocketCategories` constants) |\n| `subCategory` | `string` | - | Filter by subcategory |\n| `page` | `number` | - | Page number for manual pagination |\n\n#### Returns\n\nReturns `Promise\u003cBlocketAd[]\u003e` - an array of ad objects.\n\n---\n\n### `client.findById(id)`\n\nFind a specific ad by its ID.\n\n```typescript\nconst ad = await client.findById('12345678');\n\nif (ad) {\n  console.log(ad.heading);\n  console.log(ad.price.amount);\n}\n```\n\n#### Returns\n\nReturns `Promise\u003cBlocketAd | null\u003e` - the ad object or `null` if not found.\n\n---\n\n## Response Types\n\n### `BlocketAd`\n\nEach ad object contains:\n\n```typescript\ninterface BlocketAd {\n  id: string;                    // Ad ID (string)\n  ad_id: number;                 // Ad ID (number)\n  heading: string;               // Ad title\n  location: string;              // Location name\n  canonical_url: string;         // Full URL to the ad\n\n  price: {\n    amount: number;              // Price value\n    currency_code: string;       // e.g., 'SEK'\n    price_unit: string;          // e.g., 'kr'\n  };\n\n  image: {                       // Primary image (or null)\n    url: string;\n    width: number;\n    height: number;\n  } | null;\n\n  image_urls: string[];          // All image URLs\n  timestamp: number;             // Unix timestamp\n  trade_type: string;            // e.g., 'Säljes'\n\n  coordinates?: {                // Location coordinates (if available)\n    lat: number;\n    lon: number;\n  };\n\n  labels: Array\u003c{                // Ad labels/badges\n    id: string;\n    text: string;\n    type: 'PRIMARY' | 'SECONDARY';\n  }\u003e;\n\n  flags: string[];               // e.g., ['private', 'shipping_exists']\n}\n```\n\n## Configuration\n\nCustomize the client behavior using `configure()`:\n\n```typescript\nimport client, { configure } from 'blocket.js';\n\nconfigure({\n  logLevel: 'debug',  // 'none' | 'error' | 'info' | 'debug'\n});\n```\n\n### Configuration Options\n\n| Option | Type | Default | Description |\n|--------|------|---------|-------------|\n| `logLevel` | `string` | `'error'` | Logging verbosity |\n| `apiBaseUrl` | `string` | Blocket API | Override API endpoint |\n\n## Constants\n\n### BlocketLocations\n\nSwedish regions for filtering:\n\n| Constant | Region |\n|----------|--------|\n| `BLEKINGE` | Blekinge |\n| `DALARNA` | Dalarna |\n| `GOTLAND` | Gotland |\n| `GAVLEBORG` | Gävleborg |\n| `HALLAND` | Halland |\n| `JAMTLAND` | Jämtland |\n| `JONKOPING` | Jönköping |\n| `KALMAR` | Kalmar |\n| `KRONOBERG` | Kronoberg |\n| `NORRBOTTEN` | Norrbotten |\n| `SKANE` | Skåne |\n| `STOCKHOLM` | Stockholm |\n| `SODERMANLAND` | Södermanland |\n| `UPPSALA` | Uppsala |\n| `VARMLAND` | Värmland |\n| `VASTERBOTTEN` | Västerbotten |\n| `VASTERNORRLAND` | Västernorrland |\n| `VASTMANLAND` | Västmanland |\n| `VASTRA_GOTALAND` | Västra Götaland |\n| `OREBRO` | Örebro |\n| `OSTERGOTLAND` | Östergötland |\n\n### BlocketCategories\n\nMain categories for filtering:\n\n| Constant | Category |\n|----------|----------|\n| `AFFARSVERKSAMHET` | Affärsverksamhet |\n| `DJUR_OCH_TILLBEHOR` | Djur \u0026 Tillbehör |\n| `ELEKTRONIK_OCH_VITVAROR` | Elektronik \u0026 Vitvaror |\n| `FORDONSTILLBEHOR` | Fordonstillbehör |\n| `FRITID_HOBBY_OCH_UNDERHALLNING` | Fritid, Hobby \u0026 Underhållning |\n| `FORALDRAR_OCH_BARN` | Föräldrar \u0026 Barn |\n| `KLADER_KOSMETIKA_OCH_ACCESSOARER` | Kläder, Kosmetika \u0026 Accessoarer |\n| `KONST_OCH_ANTIKT` | Konst \u0026 Antikt |\n| `MOBLER_OCH_INREDNING` | Möbler \u0026 Inredning |\n| `SPORT_OCH_FRITID` | Sport \u0026 Fritid |\n| `TRADGARD_OCH_RENOVERING` | Trädgård \u0026 Renovering |\n\n## Examples\n\n### Search with Sorting\n\n```typescript\n// Get cheapest items first\nconst cheapest = await client.find({\n  query: 'playstation 5',\n  sort: 'PRICE_ASC',\n});\n\n// Get newest listings first\nconst newest = await client.find({\n  query: 'playstation 5',\n  sort: 'PUBLISHED_DESC',\n});\n```\n\n### Filter by Location\n\n```typescript\nimport { BlocketLocations } from 'blocket.js';\n\n// Find items in Stockholm\nconst stockholm = await client.find({\n  query: 'bicycle',\n  location: BlocketLocations.STOCKHOLM,\n});\n\n// Find items in multiple regions\nconst southern = await client.find({\n  query: 'bicycle',\n  location: [BlocketLocations.SKANE, BlocketLocations.BLEKINGE],\n});\n```\n\n### Filter by Category\n\n```typescript\nimport { BlocketCategories } from 'blocket.js';\n\n// Find electronics\nconst electronics = await client.find({\n  query: 'laptop',\n  category: BlocketCategories.ELEKTRONIK_OCH_VITVAROR,\n});\n```\n\n### Process Results\n\n```typescript\nconst ads = await client.find({ query: 'furniture' });\n\n// Filter by price\nconst affordable = ads.filter(ad =\u003e ad.price.amount \u003c 5000);\n\n// Get total value\nconst totalValue = ads.reduce((sum, ad) =\u003e sum + ad.price.amount, 0);\n\n// Extract locations\nconst locations = [...new Set(ads.map(ad =\u003e ad.location))];\n```\n\n### Error Handling\n\n```typescript\nimport client from 'blocket.js';\n\ntry {\n  const ads = await client.find({ query: 'laptop' });\n  console.log(`Found ${ads.length} ads`);\n} catch (error) {\n  console.error('Search failed:', error.message);\n}\n```\n\n## Disclaimer\n\nThis is an **unofficial** package and is not affiliated with Blocket.se. Use responsibly and in accordance with Blocket's terms of service.\n\n## License\n\n[MIT](https://github.com/rutbergphilip/blocket.js/blob/main/LICENSE) - free for personal and commercial use.\n\n---\n\n**Found this useful?** Give it a ⭐ on [GitHub](https://github.com/rutbergphilip/blocket.js)!\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frutbergphilip%2Fblocket.js","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Frutbergphilip%2Fblocket.js","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Frutbergphilip%2Fblocket.js/lists"}