API referenceBeta

NorScout API

Search companies, start an enrichment job and poll for email and phone. Poll unlocked radar events for companies you monitor.

Authentication

Create an API key in /dashboard/settings and send it as a bearer token on every request.

Enrichment endpoints require enrichment:read or enrichment:write.

Required header

Authorization: Bearer <api-key>

Request format

Content-Type: application/json
POST/api/v1/companies/search

Searches companies with the same public filter surface as NorScout search. Use any active NorScout API key.

Request body

countrystring

Company country. Defaults to NO when omitted.

NOSE
querystring

Company name or organization number. Maximum 200 characters.

industriesstring[]

NACE industry codes, for example 62.010.

locationsobject[]

Locations in the same shape used by NorScout search.

countrystring

Optional location country. Defaults to NO if omitted and must match the top-level country.

NOSE
typestringrequired

Location kind. Use region only with country NO.

citymunicipalitycountyregion
namestringrequired

Location value. Use a city or municipality name, a county code such as 03, or one of the Norwegian region keys: sornorge, vestlandet, nordnorge.

min_revenuenumber

Minimum revenue in full local-currency values. Use 0 or a positive number. Use 10000000 for 10 million.

max_revenuenumber

Maximum revenue in full local-currency values. Use 0 or a positive number. Must be greater than or equal to min_revenue.

min_employeesinteger

Minimum employee count. Use 0 or a positive integer.

max_employeesinteger

Maximum employee count. Use 0 or a positive integer.

exclude_holdingboolean

Exclude holding companies.

exclude_enkboolean

Exclude Norwegian sole proprietorships. Ignored for Sweden.

sort_bystring

Sort field.

namenumber_of_employeesrevenue
sort_directionstring

Sort direction.

ascdesc
limitinteger

Page size. Defaults to 10. The API returns at most 100 rows.

offsetinteger

Zero-based result offset inside the accessible result window. Use 0 or a positive integer.

Location examples
[
  { "type": "city", "name": "OSLO" },
  { "type": "municipality", "name": "ASKER" },
  { "country": "NO", "type": "county", "name": "03" },
  { "country": "NO", "type": "region", "name": "vestlandet" }
]

Response fields

companiesobject[]

Company rows returned for this page.

idinteger

NorScout company ID.

org_numberstring

Company organization number.

namestring

Company legal name.

ceo_namestring | null

CEO or general manager name when available.

chairman_namestring | null

Chairman name when available.

contact_person_namestring | null

Contact person name when available.

industrystring | null

Primary industry name.

business_citystring | null

Registered business city.

business_municipalitystring | null

Registered business municipality.

business_addressstring | null

Registered business address.

business_country_codestring | null

Registered business country code.

number_of_employeesinteger | null

Registered employee count.

revenuenumber | null

Latest available revenue.

period_fromstring | null

Start date for the financial period behind revenue.

period_tostring | null

End date for the financial period behind revenue.

websitestring | null

Company website.

emailstring | null

Company email address.

phonestring | null

Company phone number.

registered_in_registry_datestring | null

Date when the company was registered.

paginationobject

Page metadata.

limitinteger

Page size used for this response.

offsetinteger

Offset used for this response.

has_moreboolean

True only when more rows are available inside the allowed window.

totalinteger

Number of matching companies available within the current plan and quota window.

total_matchinginteger

Raw number of companies matching the filters before plan and quota caps.

usageobject

Shared monthly company data allowance across CSV exports and API search.

limitinteger

Monthly company data allowance for the account.

exports_usedinteger

Rows already used by CSV exports in this billing period.

company_search_rows_usedinteger

Rows already returned by API company search in this billing period.

remaininginteger

Rows remaining after this request.

request_idstring

Request identifier.

Required filters

Add at least one of query, industries, locations, revenue range, or employee range. Exclusion-only searches are rejected.

Quota and pagination

  • CSV exports and API company search share the same monthly company data allowance.
  • total_matching is the raw match count before caps. total is what this account can access inside the current plan and quota window.
  • limit defaults to 10 and is capped at 100 rows per request.
  • When the monthly allowance is exhausted, the API returns 402 with external_api_export_limit_exceeded.
Request example
curl -X POST 'https://www.norscout.com/api/v1/companies/search' \
  -H "Authorization: Bearer $NORSCOUT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "country": "NO",
    "industries": ["62.010"],
    "locations": [
      {
        "country": "NO",
        "type": "city",
        "name": "OSLO"
      }
    ],
    "min_revenue": 10000000,
    "limit": 50,
    "offset": 0
  }'
Response example
{
  "companies": [
    {
      "id": 123,
      "org_number": "123456789",
      "name": "Acme AS",
      "ceo_name": "Kari Nordmann",
      "chairman_name": null,
      "contact_person_name": null,
      "industry": "Computer programming activities",
      "business_city": "Oslo",
      "business_municipality": "Oslo",
      "business_address": "Dronning Eufemias gate 1",
      "business_country_code": "NO",
      "number_of_employees": 24,
      "revenue": 18400000,
      "period_from": "2025-01-01T00:00:00.000Z",
      "period_to": "2025-12-31T00:00:00.000Z",
      "website": "https://acme.no",
      "email": "post@acme.no",
      "phone": "+47 22 00 00 00",
      "registered_in_registry_date": "2018-03-12T00:00:00.000Z"
    }
  ],
  "pagination": {
    "limit": 50,
    "offset": 0,
    "has_more": true
  },
  "total": 5000,
  "total_matching": 12840,
  "usage": {
    "limit": 5000,
    "exports_used": 50,
    "company_search_rows_used": 200,
    "remaining": 4750
  },
  "request_id": "req_123456789"
}

Start a job

POST/api/v1/enrichment

Starts an enrichment job and returns a jobId and statusUrl immediately.

Request body

outputstring[]required

Requested fields. Supported values: email, phone, or both.

rowsobject[]required

People to enrich. The limit is 100 rows per minute.

company_namestringrequired

Company name for the contact.

country_codestringrequired

2-letter ISO country code, for example NO or SE.

person_namestringrequired

Full name of the person to enrich.

rolestring

Role or title. Improves matching quality.

company_websitestring

Company domain or URL. Improves matching quality.

company_org_numberstring

Optional organization number. Improves company matching quality.

webhook_urlstring

Public HTTPS endpoint. Norscout posts the final result payload there when the job finishes. Omit it if you want to poll the status URL instead.

sourcestring

Optional caller-defined label. Returned in the start response when supplied.

Get the results with polling

Read statusUrl from the POST response, then call it every few seconds until status becomescompleted, failed, or cancelled. The final response includes row-level results in submitted order.

Get the results with a webhook

Add webhook_url to the POST body to receive the result automatically when the job finishes. Your webhook endpoint must accept POST requests. The payload uses the same row order as your request.

Email results

Email enrichment looks for a direct work email for the person you submitted. Generic company inboxes like post@, info@, and kontakt@ are not returned as person email results. If no direct email is found, email is null and notes.email explains the result when available.

Limits

  • 100 rows per minute per user.
  • Credits are reserved when the job starts.
Request example
curl -X POST 'https://www.norscout.com/api/v1/enrichment' \
  -H "Authorization: Bearer $NORSCOUT_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "output": ["email", "phone"],
    "webhook_url": "https://example.com/api/webhooks/enrichment",
    "rows": [
      {
        "company_name": "Acme AS",
        "country_code": "NO",
        "person_name": "Kari Nordmann"
      }
    ]
  }'
Response example
{
  "jobId": 91234,
  "status": "queued",
  "statusUrl": "/api/v1/enrichment/91234",
  "requestId": "req_123456789",
  "requestedOutput": ["email", "phone"],
  "receivedRows": 1,
  "credits": { "reserved": 2, "charged": 0 }
}

Check a job

GET/api/v1/enrichment/{jobId}

Returns only the current job status and final row-level results.

Response fields

statusstring

Current job state. Poll again while it is active. Read rows when it reaches a final state.

activecompletedfailedcancelled
rowsobject[]

Final row-level results in the same order as the rows you submitted. Empty while the job is still active.

statusstring

Per-row result state.

completednot_foundfailedpartial
emailstring | null

Resolved email value when email was requested.

phonestring | null

Resolved phone value when phone was requested.

notesobject

Per-output explanation keyed by email and phone when a value is missing, partial, or failed.

Polling

  • Use the returned statusUrl from the POST response.
  • Poll every 2-5 seconds while status is active. The limit is 60 status checks per minute per user.
  • If you receive 429, wait for the Retry-After value before polling again.
  • Use rows after status becomes completed, failed, or cancelled.

Webhooks

Add webhook_url when starting a job. Your endpoint must accept POST requests. NorScout sends the result there when the job finishes. If you omit webhook_url, poll this endpoint instead.

Active response
{
  "status": "active",
  "rows": []
}
Finished response
{
  "status": "completed",
  "rows": [
    {
      "status": "completed",
      "email": "kari@acme.no",
      "phone": "+47 90 12 34 56",
      "notes": {
        "email": null,
        "phone": null
      }
    }
  ]
}

Radar feed

GET/api/v1/radar/feed

Returns unlocked radar events. Use locked_count to see how many locked events match the same filters.

Query params

limitinteger

Page size. Defaults to 50. Maximum 100.

cursorstring

Opaque cursor from pagination.next_cursor in the previous response.

signal_typestring

Filter by one radar signal type.

org_numberstring

Filter by company organization number.

sincestring

Only return events with detected_at greater than or equal to this ISO 8601 datetime.

Response fields

eventsobject[]

Unlocked radar events. Locked events are not included.

locked_countinteger

Number of locked events matching the same filters. Counts raw rows; events may deduplicate address_changes.

paginationobject

Cursor pagination metadata for the feed.

next_cursorstring | null

Pass this value as cursor on the next request to fetch older events.

has_moreboolean

True when more unlocked events are available.

limitinteger

The page size used for this response.

request_idstring

Request identifier.

Polling

  • Poll every 1-5 minutes.
  • Pass since for incremental sync.
  • Pass cursor from pagination.next_cursor for older pages.
  • If locked_count is greater than 0, unlock those events in NorScout to include them in events.
Request example
curl 'https://www.norscout.com/api/v1/radar/feed?limit=50' \
  -H "Authorization: Bearer $NORSCOUT_API_KEY"
Response example
{
  "events": [
    {
      "id": 2011,
      "company": {
        "name": "Acme AS",
        "org_number": "123456789"
      },
      "signal_type": "news_pr",
      "title": "Office move to Nedre Vollgate 5",
      "summary": "Acme AS moved its office to Nedre Vollgate 5.",
      "detected_at": "2026-06-07T10:00:00.000Z",
      "event_date": "2026-06-07",
      "sources": [
        {
          "url": "https://example.com/article",
          "title": "Example article",
          "published_at": "2026-06-07T09:30:00.000Z"
        }
      ]
    }
  ],
  "locked_count": 0,
  "pagination": {
    "next_cursor": null,
    "has_more": false,
    "limit": 50
  },
  "request_id": "req_123456789"
}

Radar subscriptions

GET/api/v1/radar/subscriptions

Returns active radar subscriptions and tracked_companies (companies with active monitoring).

Request example
curl 'https://www.norscout.com/api/v1/radar/subscriptions' \
  -H "Authorization: Bearer $NORSCOUT_API_KEY"
Response example
{
  "subscriptions": [
    {
      "id": 1,
      "company": {
        "name": "Acme AS",
        "org_number": "123456789"
      },
      "signal_type": "job_openings",
      "status": "active",
      "tracking_status": "active",
      "last_event_at": "2026-06-07T10:00:00.000Z",
      "created_at": "2026-05-01T08:00:00.000Z"
    }
  ],
  "tracked_companies": 1,
  "request_id": "req_123456789"
}

Rate limits

Reference limits

company search

60 requests per minute per API key. Each request returns at most 100 rows.

enrichment rows

100 rows per minute per user.

status polling

60 status checks per minute per user. If you receive 429, wait for the Retry-After value before polling again.

radar feed

60 requests per minute.

Errors

Common errors

400

Invalid request body, unsafe webhook URL, or invalid query params.

401 / 403

Invalid or inactive API key.

402

Not enough credits for enrichment, or the monthly company data allowance is exhausted.

404

Job not found.

429

Rate limit reached.