French Company Search – SIREN, SIRET & NAF (Sirene) avatar

French Company Search – SIREN, SIRET & NAF (Sirene)

Pricing

$2.50 / 1,000 companies

Go to Apify Store
French Company Search – SIREN, SIRET & NAF (Sirene)

French Company Search – SIREN, SIRET & NAF (Sirene)

Search French companies by name, SIREN, SIRET, NAF code, department or legal form in the open Sirene data. Legal entities only: no directors, no sole traders. Licence attribution in every record, optional new-or-changed mode.

Pricing

$2.50 / 1,000 companies

Rating

0.0

(0)

Developer

Francesco Antonio Russo

Francesco Antonio Russo

Maintained by Community

Actor stats

0

Bookmarked

2

Total users

1

Monthly active users

4 days ago

Last modified

Share

Look up French companies by name, SIREN, SIRET, NAF (APE) activity code, department, postal code, legal form and size, and get clean, flat JSON records. The data is the open Sirene register published by INSEE, read through the public Recherche d'entreprises API (no API key, no scraping).

Three things make this Actor different on purpose:

  1. Legal entities only, and no people as such. No directors, shareholders or elected officials are requested, delivered or logged; no sole traders (entrepreneurs individuels) and no groups of natural persons (indivisions and de-facto companies entre personnes physiques, see the exact list below); nothing marked as not publicly diffusible. What is delivered is the Sirene record of a legal entity, and a legal entity's registered name and the head-office address can contain a person's name (a SAS named after its founder, a civil real-estate company named after its owner): they are public company data, delivered as the source publishes them (see "Personal data (GDPR)" below).
  2. The licence attribution is in every record. The Sirene data is released under the Licence Ouverte 2.0, which requires the source and the update date to be named. Each record carries source, sourceLicense, sourceUpdatedAt and retrievedAt, so the attribution travels with the data into your CRM or warehouse.
  3. A "new or changed only" mode. Schedule the Actor and receive only the companies that appeared or changed since your last run, with the list of fields that changed.

This Actor is an independent tool. It is not an official service and is not endorsed by, or affiliated with, INSEE, DINUM, Etalab or any French public body. The data is informational; it is not a legal extract (no Kbis) and must not be used as proof of a company's status.

Who it is for

  • KYB and onboarding checks: confirm that a SIREN/SIRET exists, is active, and what its legal form, activity code and head office are.
  • CRM enrichment and deduplication: turn a list of company names or identifiers into normalised records with stable keys.
  • Market mapping and lead lists: "all active SAS with an establishment in Lyon and 10 to 49 employees in NAF 62.01Z", delivered with the head-office address and coordinates and the list of their establishments in Lyon.
  • Monitoring: run it on a schedule with onlyNewOrChanged to follow a segment over time.

Input

FieldWhat it does
queriesCompany names (free text), SIREN (9 digits), SIRET (14 digits, spaces allowed) or a French VAT number (FR + 2-digit key + SIREN, for example FR27552032534, read as its SIREN; only the arithmetic of the key is checked, not whether the number is registered for VAT, and no VAT data is delivered). SIREN and SIRET are checked with the Luhn algorithm; an invalid number produces a free invalid_identifier record and no request. Leave empty to search with filters only. A name search delivers only companies that carry the words of your query in their own names (legal name, acronym, trade names of the head office or of an establishment, accents and case ignored, ligatures spelled out so Sœur = Soeur and Straße = Strasse, whole words only: Tech does not find TECHER, Total Energies does not find ENERGIE TOTALE; a plural s or x tolerated in either direction on words of more than 3 letters, and words written together or apart are the same, Total Energies = TOTALENERGIES, see "Other spellings" below; the words of your query may come from different names of the same company, for example the legal name and the trade name of a closed establishment): the source also matches the text against company directors, and a company found only through a director is not delivered. Those results are free and counted in the SUMMARY as notMatchingName. Legal-form words are optional: the Sirene name is "DANONE", not "DANONE SA", so sa, sas, sasu, sarl, eurl, snc, sca, scs, sci, sel, selarl, selas, scp, scop, se (also written S.A., S.A.S....) and the generic words societe, ste, ets, etablissement(s) are not needed to match; a company that has them in its name comes first. The source matches the text against its own fields, not only the Sirene name (live check: "Société Danone" does not find DANONE), so a name that contains such words is also asked without them, after the query as you typed it, until maxResultsPerQuery is reached (a company met twice counts once; the query of the rows stays what you typed). Other spellings. The source searches word by word: Total Energies does not find TOTALENERGIES and SaintGobain does not find SAINT GOBAIN. So a name of several words is also asked written together (Total Energies is also asked as TotalEnergies), and a name with a capital letter inside a word is also asked written apart (SaintGobain is also asked as Saint Gobain). The query as you typed it always comes first; the other spellings are asked only if maxResultsPerQuery is not reached yet, each other spelling is one more search (up to 3 more per query, each can read several pages), but all of them share the page ceilings of a name search below, the speed limit and the spending limit. A word typed in one block without capitals (saintgobain) is never cut, because there is no safe place to cut it: if the source finds nothing, try the words apart. "Danone SA", "Danone SAS" and "Société Danone" therefore deliver DANONE (552032534). Every other word is required, groupe included: "Danone France" does not deliver DANONE (its names do not contain France), it delivers the companies whose names do, such as DANONE PRODUITS FRAIS FRANCE. A query made only of optional words (for example SCI) requires them. SIREN and SIRET are not subject to this rule. A name of one character, or made only of articles (a, de la), is refused with a free invalid_identifier row. Identifiers copied from documents or spreadsheets are read when the recovery is certain: 552 032 534 RCS Paris (the RCS number is the SIREN) and 5.52032534E8 (scientific notation) give the SIREN if the number passes the check; a number of 8 or 13 digits is refused with a hint (leading zero lost?, and the valid number if adding the zero gives one).
departments, postalCodes, communeCodes, regionsWhere the company has an establishment, not only its head office (department codes like 75, 2A, 971; 5-digit postal codes, a space inside as in 69 001 is accepted; INSEE commune codes; INSEE region codes). See "Geographic filters" below. Paris 75056, Lyon 69123 and Marseille 13055 are expanded automatically to their arrondissement codes (75101-75120, 69381-69389, 13201-13216), because Sirene registers the establishments of these cities by arrondissement and almost none under the city code; the SUMMARY says so in the warnings of the search, and a company present in several arrondissements is delivered, and charged, once.
nafCodes, nafSectionsMain activity: NAF rev. 2 codes like 62.01Z (the 732 codes of the current nomenclature; any other value, including a NAF 2025 code such as 70.10Y, stops the run before any request with a message that says so), or section letters A to U.
legalFormCodesINSEE legal form codes like 5710 (SAS), 5499 (SARL), 5599 (SA). Codes starting with 1 (sole traders) and the four codes of groups of natural persons (2110, 2210, 2310, 2385) are refused.
companyCategoriesPME, ETI, GE.
employeeRangesINSEE employee range codes (11 = 10-19, 12 = 20-49, ...).
statusany (default), active or closed.
maxResultsPerQueryDefault 20 (a cheap first try; raise it when the sample looks right). Companies taken from each query (or from the filter search). Privacy exclusions, results left out because the name does not match, duplicates and (with onlyNewOrChanged) unchanged companies do not count.
onlyNewOrChangedDefault off. See below.
requestsPerSecondDefault 2, maximum 2 (the Actor stays gentle with a public service).

Wrong values (a malformed department, NAF code, postal code...) stop the run immediately with a clear message, before any request is made.

Filters apply to name searches and to filter-only searches. A SIREN or SIRET is looked up as it is: filters are not applied to it.

Example input:

{
"queries": ["DANONE", "552032534"],
"departments": ["75"],
"nafCodes": ["62.01Z"],
"status": "active",
"maxResultsPerQuery": 100
}

Output

One dataset record per company. Every field is always present (null when the source has no value) and has a stable type. This is a real record, obtained by looking up SIREN 552032534:

{
"status": "active",
"query": "552 032 534",
"queriedSiret": null,
"establishmentStatus": null,
"establishmentClosedDate": null,
"requestedEstablishment": null,
"siren": "552032534",
"siret": "55203253400703",
"name": "DANONE",
"legalName": "DANONE",
"acronym": null,
"legalFormCode": "5599",
"legalFormLabel": "SA à conseil d'administration (s.a.i.)",
"nafCode": "70.10Z",
"nafCodeNaf25": "70.10Y",
"nafSection": "M",
"companyCategory": "GE",
"employeeRangeCode": "42",
"employeeRangeLabel": "1 000 à 1 999 salariés",
"employeeRangeYear": 2024,
"headOfficeIsEmployer": true,
"creationDate": "1955-01-01",
"closureDate": null,
"establishmentCount": 19,
"openEstablishmentCount": 3,
"address": "59-61 RUE LA FAYETTE 75009 PARIS",
"postalCode": "75009",
"city": "PARIS",
"cityCode": "75109",
"department": "75",
"region": "11",
"latitude": 48.8763540066087,
"longitude": 2.34353640229216,
"headOfficeCreationDate": "2025-08-19",
"headOfficeStatus": "active",
"headOfficeInArea": null,
"matchedEstablishments": null,
"sourceUpdatedAt": "2026-09-10T13:14:57",
"change": null,
"changedFields": null,
"duplicateOf": null,
"note": null,
"source": "INSEE – base Sirene (www.insee.fr), retrieved through the API Recherche d'entreprises (DINUM)",
"sourceLicense": "Licence Ouverte 2.0 / Open Licence 2.0 (Etalab)",
"retrievedAt": "2026-10-13T13:12:00.000Z"
}

Notes on the fields:

  • siren identifies the legal unit; siret is the SIRET of its head office. If you look up a SIRET, the company is delivered with queriedSiret set to the number you asked for (the head office or another establishment); each SIRET of the input gets its own record, even when its SIREN or another SIRET of the same company is in the input too.
  • requestedEstablishment: the establishment you asked for. In a SIRET lookup, the top-level fields (siret, address, postalCode, city, nafCode, employee range, coordinates...) stay those of the company and its head office; the establishment of the SIRET you typed is in the requestedEstablishment object: siret, isHeadOffice, status, closedDate, address, postalCode, city, cityCode, department, nafCode, employeeRangeCode, employeeRangeLabel and tradeNames, all read from the source (the source gives no department for an establishment: it is read from the first digits of its commune code). It is null for every other kind of query. If the source marks the establishment as not publicly diffusible, requestedEstablishment is null, a note says so and the company record is still delivered (and charged, it is real data).
  • SIRET lookups and closed establishments. For a SIRET lookup, establishmentStatus (active / closed) and establishmentClosedDate describe the establishment you asked for, while status is always the status of the legal unit. A closed establishment of an active company is delivered (and charged, it is real data) with establishmentStatus: "closed", its closing date and a note saying so. In other searches both fields are null.
  • name is the source's full name (nom complet): it can repeat the acronym or a trade name in brackets, for example PYRAMIDE CONSTRUCTION GROUP (PCG); legalName is the bare legal name and acronym the acronym.
  • legalFormLabel and employeeRangeLabel come from the INSEE tables shipped with the Actor (data/, source written in each file), in French.
  • nafCode is NAF rev. 2 (the code in force today) and is the one to use in the nafCodes filter; nafCodeNaf25 is the NAF 2025 code when Sirene already publishes it, and the API does not accept it as a filter (copying it into nafCodes is refused with a clear message). The list of accepted rev. 2 codes is data/naf-rev2.json (read from the API on 2026-10-14); it will be updated when the API accepts the NAF 2025 codes.
  • Geographic filters. A department, postal-code, commune or region filter matches every company that has an establishment in that area. The address, postalCode, city, department, coordinates and siret of the record are always those of the head office, which can be elsewhere (a Paris-based group with a shop in Lyon matches "Lyon" with a Paris head office). So with such a filter every record also carries headOfficeInArea (true if the head office itself is in the area) and matchedEstablishments: up to 5 establishments the source reports inside the area, each with siret, address, postalCode, city, status and isHeadOffice (head office first, then open, then closed; the source itself reports at most 10). Without a geographic filter both fields are null. When a very large search is split automatically, the list shows the establishments found in the first part of the split that met the company.
  • latitude and longitude are numbers (the source sends them as text).
  • status is the administrative status of the legal unit (active / closed); headOfficeStatus that of the head-office establishment; establishmentStatus that of the establishment of a SIRET lookup.
  • headOfficeIsEmployer is the Sirene employer flag (caractère employeur) of the head-office establishment (true / false, null when Sirene does not say). The flag is empty at legal-unit level in the source, so the head office's is the one delivered.
  • duplicateOf is filled only on duplicate rows (see below): the earlier entry that already handled the company.
  • sourceUpdatedAt is INSEE's own update date for the unit, exactly as published (no time zone).
  • Only fields of INSEE origin are delivered. Flags from other registers that the API also exposes (RGE, ESS, organic, elected officials...) are deliberately left out.

Records without company data (always free)

Every entry of queries produces at least one row, so a list of 200 identifiers comes back as 200 or more rows you can join on query. Only the identifier you typed (and a note) is filled in; every other field is null, and none of these rows is ever charged.

statusMeaning
not_foundNo such SIREN/SIRET in the data served by the API. For a name or filter search: the search had no result to deliver (the note says how many results the source reported and why none was delivered).
invalid_identifierThe number fails the SIREN/SIRET check (or the key of a VAT number), has a length that is neither 9 nor 14 (the note asks whether a leading zero was lost), or the entry is made only of symbols such as &, or is a single character or only articles (a, de la). No request was made.
excluded_individualThe SIREN/SIRET belongs to a sole trader or to a group of natural persons (legal forms 1xxx, 2110, 2210, 2310, 2385). Not delivered, by design.
excluded_privacyThe unit is not fully publicly diffusible. Not delivered.
duplicateThe entry repeats an earlier entry of the same input (the same SIRET written twice, a SIREN and its VAT number...), or its company (SIREN) was already handled by an earlier entry of this run: a SIREN found by an earlier name search, a SIREN given twice... siren and duplicateOf (the earlier entry) tell which; the company is delivered once. A SIRET is never a duplicate of a SIREN, nor of another SIRET of the same company: it is another entity and gets its own record, with requestedEstablishment, charged like any record with data (a SIREN and one of its SIRET, or two SIRET of one company, give two records). A name or filter search whose companies were all handled by earlier entries also gets one such row.
unchangedonlyNewOrChanged mode: the SIREN/SIRET is already delivered by an earlier run and nothing changed since.

A name or filter search that delivers at least one company has no such row, and in onlyNewOrChanged mode a name or filter search whose companies are all unchanged delivers nothing at all (the SUMMARY counts them): a scheduled run only carries news. An entry that could not be answered (the source kept failing) or was not run because the spending limit was reached has no row: it is failed or skipped in the SUMMARY.

Run summary

A SUMMARY record in the key-value store lists, for each query: how many results the API reported (totalFound, added up in foundByApi of the totals: the source also matches a name against company directors, so both numbers count those results too, although they are never delivered; neither is the number of companies you can expect), how many were delivered, how many were skipped as unchanged or as duplicates, how many were excluded for privacy (a count only, never a name), how many were left out because the query words are in none of their names (notMatchingName), how many requests failed, plus the stopReason and finishedAt. It is also written while the run is going on, so a run that is stopped still leaves an honest summary.

What this Actor does not contain, and why

  • No directors, shareholders or beneficial owners. They are natural persons.
  • No sole traders / individual entrepreneurs. Their name and address are personal data. A search never returns them: the API is asked to filter them out, and anything that still arrives with a legal form starting with 1, an individual-entrepreneur flag, or a diffusion status other than "fully diffusible" is discarded by the Actor itself. Names of discarded results are never logged.
  • No groups of natural persons. These legal forms have no legal personality of their own and are named after the people who form them, so they are discarded as well (free, counted in excludedPrivacy; a SIREN/SIRET lookup gives an excluded_individual record). The exact list of excluded legal forms:
    • every code starting with 1 (sole traders and other individuals);
    • 2110 Indivision entre personnes physiques;
    • 2210 Société créée de fait entre personnes physiques;
    • 2310 Société en participation entre personnes physiques;
    • 2385 Société en participation de professions libérales (its members are individual professionals). The variants avec personne morale (2120, 2220, 2320) include a legal entity and are delivered.
  • No financial statements, no VAT data, no register extracts.

This is a design choice, not a limitation to be configured away.

Source and licence

The data is the Sirene register of INSEE, served by the API Recherche d'entreprises (DINUM), which is open and needs no key. Sirene is published under the Licence Ouverte 2.0 (Etalab), which allows commercial reuse provided that the source and the date of the last update are mentioned: that is what source, sourceLicense and sourceUpdatedAt are for. Keep them when you pass the data on, and do not suggest that INSEE, DINUM or the French State endorse your product.

Only new or changed companies

With onlyNewOrChanged on, the Actor remembers, between runs, a fingerprint of the fields it delivered for every SIREN, and one for every SIRET looked up (the fingerprint of a SIRET also covers the state of its establishment, establishmentStatus and establishmentClosedDate: a SIRET that closes is delivered again as changed) (in a named key-value store, fr-company-search-state, shared by all your runs of this Actor). Then:

  • a company never delivered before is delivered with change: "new";
  • a company whose delivered data differs from the last delivery is delivered with change: "changed" and changedFields listing the fields;
  • an unchanged company is skipped and not charged, and it does not use up maxResultsPerQuery: the Actor keeps reading the results until it has delivered as many new or changed companies as you asked for, or until the search is exhausted. So a segment larger than your limit is worked through in successive runs (5 new, then the next 5, and so on).
  • Page ceiling. To keep the load on the source reasonable, in this mode the Actor reads at most 500 pages (12,500 results) per query. If that ceiling stops a search before it has found enough new or changed companies, the query is marked partial in the SUMMARY (pageCapReached: true, totals.stoppedByPageCeiling) with a warning, and the log says so: narrow the filters (department, postal code, NAF code) to reach the rest.

Reset the memory. To start again from zero (everything is "new" again, and charged again), delete the named key-value store fr-company-search-state: on the platform, Storage > Key-value stores > that store > Delete; in a local run, delete the folder key_value_stores/fr-company-search-state.

Cost of a first run. In this mode too, the first run delivers every company it meets as "new" and is charged like a normal run: a first run that delivers 20 companies costs 20 times the price of one Company event (for an event priced at 0.0025, 20 x 0.0025 = 0.05, in the currency of the price shown on the Actor page). With the default of 20 per query, a segment of 500 companies is worked through in 25 successive runs, and the next runs only charge the news.

Only what was actually delivered is remembered, so a run stopped by its budget or by an error does not hide anything: the rest is "new" next time. The filters are not part of the memory: a company met again under different filters is compared as it is. INSEE's own update date (sourceUpdatedAt) does not count as a change by itself.

How much does it cost?

$2.50 per 1,000 companies ($0.0025 per company record with data). Everything else is free: not found, invalid identifiers, duplicates, unchanged companies, excluded units, failed requests. There is no start fee and no fee per query.

You runRecords with dataCost at most
200 SIREN/SIRET from your CRM≤ 200$0.50
100 company names, default maxResultsPerQuery 20≤ 2,000$5.00 (maxResultsPerQuery: 5: ≤ $1.25)
A segment: active SAS in one department and NAF section, 1,000 results1,000$2.50
The same segment again a week later with onlyNewOrChangedonly what changedusually a few cents

To keep spending under control: maxResultsPerQuery caps each name or filter search; the maximum cost per run you set in Apify Console (or maxTotalChargeUsd in the API) is never exceeded — the Actor stops before it. For lead lists use status: "active": closed companies have data and are charged.

What is charged

One event, Company: a record that carries company data (status active or closed) and is delivered to the dataset. Not charged: every row whose status is not active or closed (not_found, invalid_identifier, excluded_individual, excluded_privacy, duplicate, unchanged), companies skipped as unchanged inside a search, results left out for privacy or because the name does not match, and failed requests. The Actor never delivers more records than your spending limit allows and stops calling the API once the limit is reached. If the Actor is started with pay-per-event pricing that does not include the Company event, it refuses to run.

Limits to know

  • 10,000 results per search. The API never returns more than 10,000 companies for one search. If a search reports 10,000 and you asked for more, the Actor splits it automatically (by commune when you listed several, Paris, Lyon and Marseille arrondissements included; otherwise by department, or by the departments you listed, then by NAF section or NAF code) and removes duplicates by SIREN. If a slice still reaches the limit, the first 10,000 of that slice are delivered and the summary says so; narrow the filters (postal code, NAF code, legal form) to reach the rest. The overseas collectivities outside the five overseas departments are not part of the automatic split.
  • Speed. The public API allows at most 7 requests per second per IP address, and 30 per second for all users of the same network; it can lower these limits under load. The Actor sends one request at a time, never more than requestsPerSecond (default and maximum 2), and identifies itself in the User-Agent. On a 429 it waits for the Retry-After delay (at most 60 s) and retries up to 4 times, slowing down for the rest of the run; on a server error it retries twice. A part of a search that still fails is marked failed in the summary, free of charge, and the run continues; five failed requests in a row stop the run. No proxy and no IP rotation are used.
  • Page ceilings of a name search (with or without onlyNewOrChanged). The source also answers a name with companies found through their directors, which are never delivered, so a name with few real matches (a person's name, say) could make the Actor read hundreds of pages for a handful of companies. A name search therefore stops after 5 pages in a row without a single company that has your words in its names, and anyway after 20 such pages in total (a page that brings at least one match, and an empty page, does not count; 500 results read without any match at most). When a ceiling stops a search, the query is partial in the SUMMARY (pageCapReached: true, totals.stoppedByPageCeiling) with a warning in the SUMMARY and in the log, the companies found before are delivered, and a search that found nothing gets a not_found row whose note says the search was stopped. Add filters (department, postal code, NAF code) or a more distinctive name to go further. Searches by filters only and SIREN/SIRET lookups have no such ceiling.
  • 25 results per request, one page at a time.
  • No filter on creation date: the API does not offer one. Use onlyNewOrChanged to follow new companies in a segment.
  • No guarantee from the source. The API has no published service-level commitment. Records can lag the official register, and recently created or modified units may not be there yet.
  • Not every French entity is public. Units that are not diffusible do not appear in the API at all.

FAQ

Why is a company I know "not found"? The search reads the Sirene names (legal name, acronym, trade names and signs). Articles, prepositions and legal forms in your text are optional ("Le Garage Dupont" finds GARAGE DUPONT, "Danone SA" finds DANONE), but every other word must be in a name of the company. Try the SIREN, or fewer words.

Is the first result of a name search the company I mean? Not always. Results come in the order of the source, which favours names that match the words exactly: "LVMH" first returns two small property companies called LVMH, and "Michelin" puts the tyre maker sixth, after namesakes. To identify one company for sure, search by SIREN or SIRET; with names, keep several results (maxResultsPerQuery 5-10) and pick by legalFormLabel, companyCategory, openEstablishmentCount, address or status.

With a place filter, is status: active about the place? status is the company's. With status: "active" and a department, postal code or commune filter, a company whose establishments in that area are all closed is left out (free, counted in the SUMMARY as noOpenEstablishmentInArea). Each record says whether the head office is in the area (headOfficeInArea) and lists up to 5 matching establishments with their status.

Why are sole traders missing? By design: sole traders (legal forms 1xxx), groups of natural persons and units without legal personality are never delivered, because their names are people's names. Only legal entities are returned.

How fresh is the data? It comes from the public Recherche d'entreprises API, which follows the Sirene database (INSEE) with a delay of about one day.

How do I call it from my code? POST https://api.apify.com/v2/acts/far003~french-company-search-sirene/run-sync-get-dataset-items?token=<YOUR_TOKEN> with a JSON body such as {"queries": ["DANONE", "552032534"]} returns the records directly. With apify-client for JavaScript: const run = await client.actor('far003/french-company-search-sirene').call({ queries: ['DANONE'] }); const { items } = await client.dataset(run.defaultDatasetId).listItems();

Something looks wrong? Open an issue on the Actor's page (Issues tab) with the query and the run ID: every report is read.

Personal data (GDPR)

The Actor delivers no directors, no sole traders and no groups of natural persons (see above), but it cannot make the registered name or the head-office address of a legal entity free of personal data: some company names contain a person's name (for example a SAS or a civil real-estate company named after its owner), and the head-office address can be a private one. Nothing in the output tells you when that is the case. You remain responsible for how you use the data, for your own lawful basis, and for respecting the conditions of the Licence Ouverte 2.0 and of the French data-protection rules, including for prospecting. Nothing here is legal advice.

Running locally

npm install
npm test # unit and end-to-end tests against a local fake of the API
echo '{"queries":["552032534"]}' > storage/key_value_stores/default/INPUT.json
npm start # the records land in storage/datasets/default

To keep the storage of a local run in another folder, set CRAWLEE_STORAGE_DIR (the Apify SDK 3 ignores the older APIFY_LOCAL_STORAGE_DIR): put INPUT.json in $CRAWLEE_STORAGE_DIR/key_value_stores/default/ and start with CRAWLEE_STORAGE_DIR=/some/folder npm start. A local run sends real requests to the public API (at most requestsPerSecond per second).