# Kart.1881 Scraper (`parsebird/kart-1881-scraper`) Actor

Scrape kart.1881.no, Norway's 1881 map directory. Search companies, people or addresses and get names, addresses, phone numbers, coordinates, websites, emails and social links. Export JSON, CSV, Excel or use the API.

- **URL**: https://apify.com/parsebird/kart-1881-scraper.md
- **Developed by:** [ParseBird](https://apify.com/parsebird) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.49 / 1,000 results

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

### Kart.1881 Scraper

**Kart.1881 Scraper** extracts companies, people and addresses from [kart.1881.no](https://kart.1881.no), the map search of Norway's 1881 directory. Search by trade, name, phone number or address and get names, addresses, phone numbers, coordinates, websites, emails and social links as structured data. You don't need a 1881 account, a cookie or an API key.

<table><tr>
<td style="border-left:4px solid #1C1917;padding:12px 16px;font-weight:600">
Run any number of searches across 1881's company, person or address directory and get one clean row per result, with GPS coordinates on the list and website, email, Facebook, Instagram, extra phone numbers and opening hours when you turn on full details.
</td>
</tr></table>

##### Copy to your AI assistant

Copy this block into ChatGPT, Claude, Cursor, or any LLM to start using this actor.

```
Apify Actor: parsebird/kart-1881-scraper. Scrapes kart.1881.no, the map search of Norway's 1881 directory, without login. Call via ApifyClient: client.actor("parsebird/kart-1881-scraper").call(run_input={"searchQueries": ["restaurant"], "searchType": "company", "maxItemsPerQuery": 50, "scrapeFullDetails": true}). Inputs: searchQueries (string[], required: trade, name, phone number, address or place, optionally with a town, one search each), searchType ("company" | "person" | "address", default "company"), maxItemsPerQuery (integer, min 1, default 50), scrapeFullDetails (boolean, default false). Output: dataset rows with name, address, phone (international format with 00 prefix), id, type, lat, lon, query; with scrapeFullDetails also phoneNumber, website, email, facebook, instagram, otherLinks (string[]), contactList ({label,value}[]), openingHours ({day,hours}[]), companiesAtAddress ({name,url}[], address searches), profileUrl. Duplicates across queries are removed. Pricing: pay per result, plus a details event per result opened with scrapeFullDetails. Full API spec: https://apify.com/parsebird/kart-1881-scraper/api. Get your token: https://console.apify.com/settings/integrations.
```

### What is Kart.1881 Scraper?

**Kart.1881 Scraper** turns [1881 Kart](https://kart.1881.no) searches into a dataset. Type the same words you would type on the site, pick **company**, **person** or **address**, and click **Start**. To try it, keep the prefilled `restaurant` search, which saves 20 Norwegian restaurants with their contact details.

It works as a **1881 API alternative** for people who need Norwegian directory data in a spreadsheet or a pipeline rather than one map pin at a time. Download the results as **JSON, CSV or Excel**, or read them through the [Apify API](https://docs.apify.com/api/v2).

### What can Kart.1881 Scraper do?

- 🏢 **Search companies.** Find businesses by trade, name, phone number or trade plus town, such as `frisør trondheim`.
- 👤 **Search people.** Find listed people by name and get their listed address and phone number.
- 📍 **Search addresses and places.** Look up streets, house numbers, postcodes, towns and named places, and see which companies are registered at an address.
- 📇 **Add full details.** Get website, email, Facebook, Instagram, other links, extra contact numbers, opening hours and the 1881 profile link.
- 🧹 **Get clean results.** Repeated queries and results that appear under several queries are saved and charged once.

Because it runs on Apify, you also get:

- [Scheduling](https://docs.apify.com/platform/schedules) to refresh your data daily, weekly or at any interval
- [API access](https://docs.apify.com/api/v2) with [Python](https://docs.apify.com/api/client/python) and [JavaScript](https://docs.apify.com/api/client/js) clients
- [Integrations](https://docs.apify.com/platform/integrations) with Make, Zapier, Google Sheets, Slack and webhooks
- Export to JSON, CSV, Excel, XML and HTML

### What data can you extract from Kart.1881?

| Field | Description | Available |
|-------|-------------|-----------|
| `name` | Company, person or place name | Always |
| `address` | Address, such as `Stortingsgata 16, 0161 Oslo` | Always, when listed |
| `phone` | Main phone number, such as `004721507220` | Always, when listed |
| `id` | 1881 entry ID | Always |
| `type` | `company`, `person` or `address` | Always |
| `lat`, `lon` | GPS coordinates | Always, when listed |
| `query` | The search query that found this result | Always |
| `phoneNumber` | Main phone number from the details | Full details |
| `website` | Main website | Full details |
| `email` | Main email address | Full details |
| `facebook`, `instagram` | Social profile links | Full details |
| `otherLinks` | Other links, such as LinkedIn, YouTube or a second website | Full details |
| `contactList` | Extra contacts as label and value, such as `Mobiltelefon`, `Telefaks` or a named person | Full details |
| `openingHours` | Opening hours per day, in Norwegian, when the company lists them | Full details |
| `companiesAtAddress` | Companies registered at the address, with name and 1881 link | Full details, address searches |
| `profileUrl` | Link to the entry's page on www.1881.no | Full details, companies and people |

Not every entry lists everything. In one test of 50 restaurants, 41 had a website, 41 had an email and 35 had a Facebook page.

### How to scrape Kart.1881 step by step

1. Open [Kart.1881 Scraper](https://apify.com/parsebird/kart-1881-scraper) and sign in to Apify.
2. Add your **Search queries**, such as `restaurant bergen`, `Ola Nordmann` or `Karl Johans gate 1`.
3. Choose the **Search type**: Company, Person or Address.
4. Set **Max items per query**, the most results to save for each search.
5. Turn on **Scrape full details** if you need websites, emails and social links.
6. Click **Start** and wait for the run to finish.
7. Download your Kart.1881 data as JSON, CSV or Excel from the **Output** tab.

### Input parameters

| Parameter | Type | Required | Default | Description |
|-----------|------|----------|---------|-------------|
| searchQueries | string\[] | **Yes** | — | What to search for on 1881. Each query runs on its own. |
| searchType | string | No | `company` | `company`, `person` or `address` |
| maxItemsPerQuery | integer | No | 50 | Most results to save for each query. Minimum 1. |
| scrapeFullDetails | boolean | No | `false` | Open each result to add contact details. Adds one details event per result. |

```json
{
    "searchQueries": ["restaurant"],
    "searchType": "company",
    "maxItemsPerQuery": 50,
    "scrapeFullDetails": true
}
```

### Output example

A company with full details:

```json
{
    "name": "Restaurant Teatro",
    "address": "Stortingsgata 16, 0161 Oslo",
    "phone": "004721507220",
    "id": "105296483S1",
    "type": "company",
    "lat": 59.9135551452637,
    "lon": 10.7358512878418,
    "phoneNumber": "004721507220",
    "website": "http://restaurantteatro.no/",
    "email": "post@restaurantteatro.no",
    "facebook": "https://www.facebook.com/teatrooslo/",
    "instagram": "http://www.instagram.com/teatrooslo",
    "otherLinks": [],
    "contactList": [
        { "label": "Mobiltelefon", "value": "90 22 00 50" },
        { "label": "Eik Teater AS", "value": "90 71 77 43" }
    ],
    "openingHours": [],
    "companiesAtAddress": [],
    "profileUrl": "https://www.1881.no/restaurant/restaurant-oslo/restaurant-oslo-sentrum/restaurant-teatro_105296483S1/",
    "query": "restaurant"
}
```

An address with full details:

```json
{
    "name": "Nygata 3",
    "address": "Nygata 3, 0155 Oslo",
    "phone": null,
    "id": "F1581646",
    "type": "address",
    "lat": 59.9129784,
    "lon": 10.7505545,
    "phoneNumber": null,
    "website": null,
    "email": null,
    "facebook": null,
    "instagram": null,
    "otherLinks": [],
    "contactList": [],
    "openingHours": [],
    "companiesAtAddress": [
        {
            "name": "Alpha Revisjon AS",
            "url": "https://www.1881.no/revisor/revisor-oslo/revisor-oslo-sentrum/alpha-revisjon-as_100503190S2/"
        }
    ],
    "profileUrl": null,
    "query": "Nygata 3 Oslo"
}
```

Without full details, rows contain only `name`, `address`, `phone`, `id`, `type`, `lat`, `lon` and `query`.

### How to use the Kart.1881 API in Python and JavaScript

**Python**

```python
from apify_client import ApifyClient

client = ApifyClient("<YOUR_API_TOKEN>")

run = client.actor("parsebird/kart-1881-scraper").call(run_input={
    "searchQueries": ["restaurant bergen", "frisør trondheim"],
    "searchType": "company",
    "maxItemsPerQuery": 100,
    "scrapeFullDetails": True,
})

for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item["name"], item["phone"], item.get("email"))
```

**JavaScript**

```javascript
import { ApifyClient } from 'apify-client';

const client = new ApifyClient({ token: '<YOUR_API_TOKEN>' });

const run = await client.actor('parsebird/kart-1881-scraper').call({
    searchQueries: ['restaurant bergen', 'frisør trondheim'],
    searchType: 'company',
    maxItemsPerQuery: 100,
    scrapeFullDetails: true,
});

const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => console.log(item.name, item.phone, item.email));
```

Get your token in [Apify Console](https://console.apify.com/settings/integrations). See every option on the [API tab](https://apify.com/parsebird/kart-1881-scraper/api).

### Use cases

- **Lead lists:** build lists of Norwegian businesses by trade and town, with phone, email and website.
- **Market research:** count and map companies in a trade with their coordinates.
- **Data enrichment:** add phone numbers, websites and coordinates to a list of company names.
- **Address checks:** confirm that an address exists, get its coordinates and see which companies are registered there.
- **Directory monitoring:** schedule a run to spot new or changed entries.

### How does Kart.1881 Scraper work?

1. It runs each search query against the directory you picked.
2. It moves through the result pages until it reaches your limit or 1881 has no more results.
3. It skips results it has already saved in this run.
4. If you turned on full details, it opens each new result and adds its contact data.
5. It saves each row to your dataset as it goes, so a stopped run keeps its results.

### How much does it cost to scrape Kart.1881?

Kart.1881 Scraper uses pay-per-event pricing. Compute and proxy costs are included in the event price.

| Event | Free | Bronze | Silver | Gold |
|-------|------|--------|--------|------|
| `result-scraped`, per 1,000 | **$2.99** | **$2.49** | **$1.99** | **$1.49** |
| `details-scraped`, per 1,000 | **$0.99** | **$0.99** | **$0.99** | **$0.99** |

A result event fires for each row saved. A details event fires only when you turn on full details and the result's details open successfully. On the Free tier, 1,000 companies cost $2.99 without details and $3.98 with them. On Gold, the same runs cost $1.49 and $2.48.

Duplicates, unsearchable queries and queries with no results cost nothing. To cap your spending, set a maximum cost per run in the run options. The run stops at that limit and keeps what it saved.

### Is it legal to scrape Kart.1881?

Kart.1881 Scraper only collects data that 1881 shows publicly, without logging in. Web scraping of public data is generally legal, but what you may do with the data depends on your purpose and your country. You can read more in [Is web scraping legal?](https://blog.apify.com/is-web-scraping-legal/)

Person results and many sole-trader listings are **personal data**. The GDPR applies in Norway through the EEA, so you need a lawful basis to store or use them. Before any direct marketing, also check Norway's marketing rules and the Reservation Register (Reservasjonsregisteret). Check 1881's terms too, and ask a lawyer if you are unsure. This section is not legal advice.

### Other scrapers you may like

- [Allabolag Scraper](https://apify.com/parsebird/allabolag-company-scraper): B2B company data and leads from Sweden
- [Apple Maps Scraper](https://apify.com/parsebird/apple-maps-scraper): places, phones, websites, ratings and hours worldwide
- [Website Contact Finder](https://apify.com/parsebird/website-contact-finder): emails, phone numbers and social profiles from websites, handy for following up on the `website` field
- [YellowPages USA Lead Generator](https://apify.com/parsebird/yellowpages-scraper): business leads from the USA

### FAQ

**Do I need a 1881 account or an API key?**
No. The scraper only reads what kart.1881.no shows to any visitor.

**How many results can I get per query?**
As many as 1881 returns for that search. In our tests, `restaurant` in the company directory returned over 14,000 results, while `storgata` in the address directory stopped at 76. Address searches return far fewer results than company and person searches.

**Why does an address result have no house number?**
Without full details, 1881 can list a street without its number, such as `Storgata, 0155 Oslo`. Turn on full details to get the exact address, or include the number in your search.

**How can I search within one town?**
Add the town to the query, such as `restaurant bergen`. There's no separate location filter.

**Why did my query return nothing?**
Check the run log. 1881 answers text it can't search, such as `...`, a single letter, or a word with a long string of nonsense after it, with a fixed list of unrelated entries. The scraper detects this, skips the query, logs a warning and charges nothing. Try a simpler search.

**Can I look up a phone number?**
Yes. Enter the number without spaces, such as `21507220`, and choose the matching search type.

**Why do some rows have a different phone number in `contactList`?**
`phone` is the main number. `contactList` holds whatever else the entry lists, such as a mobile number, a fax number or a named contact, and keeps the labels 1881 uses in Norwegian.

**Are the opening hours in English?**
No. Day names stay in Norwegian (`Mandag` to `Søndag`) as 1881 shows them.

**Can I schedule recurring runs?**
Yes. Use [Apify Schedules](https://docs.apify.com/platform/schedules) to run daily, weekly or at any interval.

**Something doesn't work. Where do I report it?**
Open a ticket on the [Issues tab](https://apify.com/parsebird/kart-1881-scraper/issues). Include your run link so we can look into it.

# Changelog

This Actor's version history is a separate document: https://apify.com/parsebird/kart-1881-scraper/changelog.md

# Actor input Schema

## `searchQueries` (type: `array`):

Enter what you would type into 1881: a trade, a company or person name, a phone number, a street address or a place. Add a town to narrow it down, such as 'restaurant bergen'. Each query runs on its own.

## `searchType` (type: `string`):

Choose which part of the 1881 directory to search: companies (Firma), people (Personer) or addresses and places (Steder).

## `maxItemsPerQuery` (type: `integer`):

Set the most results to save for each search query. A query stops sooner if 1881 has no more results.

## `scrapeFullDetails` (type: `boolean`):

Open each result's details to add website, email, Facebook, Instagram, other links, extra contact numbers, opening hours and the 1881 profile link. For addresses, adds the exact address and the companies registered there. Each opened result counts as one details event.

## Actor input object example

```json
{
  "searchQueries": [
    "restaurant"
  ],
  "searchType": "company",
  "maxItemsPerQuery": 20,
  "scrapeFullDetails": true
}
```

# Actor output Schema

## `dataset` (type: `string`):

No description

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "searchQueries": [
        "restaurant"
    ],
    "searchType": "company",
    "maxItemsPerQuery": 20,
    "scrapeFullDetails": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("parsebird/kart-1881-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "searchQueries": ["restaurant"],
    "searchType": "company",
    "maxItemsPerQuery": 20,
    "scrapeFullDetails": True,
}

# Run the Actor and wait for it to finish
run = client.actor("parsebird/kart-1881-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchQueries": [
    "restaurant"
  ],
  "searchType": "company",
  "maxItemsPerQuery": 20,
  "scrapeFullDetails": true
}' |
apify call parsebird/kart-1881-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,parsebird/kart-1881-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/KMN9wiNOQaDttjlxw/builds/a99lKoZMdqAtVofNh/openapi.json
