Skip to content
firmus.shdocs

Every page's text, headings and title. Code samples are not indexed.

Run a segment

Count the active companies matching explicit filters, with four facets and a sample of ten, and save the segment to run or export it later.

A segment is a set of explicit filters over every active legal entity of the registry. The answer is the exact count, four facets that split it, and a sample of at most ten companies, each with its sources and dates. With save: true the segment is stored, so you can run it again later or export every company in it as a CSV.

Served for fr only; any other country is a 404. It needs a key with the read scope, sent from a server: a publishable fk_pub key is refused with 403 public_key_forbidden. Each request is one call — on Free, one of the month's 1 000 lookups; on Pro and Scale it spends nothing but the rate.

Run one

Keep the key out of your shell history:

read -rs FIRMUS_KEY && export FIRMUS_KEY

Computer programming and consultancy (NAF division 62) with its head office in the Rhône (69), 10 employees or more:

curl -s -X POST https://api.firmus.sh/v1/fr/segments \
  -H "Authorization: Bearer $FIRMUS_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "filters": { "activity": ["62"], "departement": ["69"], "workforce": { "from": "11" } },
    "facet_limit": 3
  }'

The answer is 200. The sample below is cut to one of its ten companies; the figures are the registry's on 1 November 2026 and move with it:

{
  "segment": null,
  "filters": {
    "activity": [
      {
        "code": "62",
        "level": "division",
        "label": "Programmation, conseil et autres activités informatiques"
      }
    ],
    "departement": ["69"],
    "workforce": { "from": { "code": "11", "label": "10 à 19 salariés" }, "to": null }
  },
  "count": 371,
  "exportable_count": 370,
  "facets": {
    "departement": { "values": [{ "value": "69", "label": null, "count": 371 }], "other": 0 },
    "activity_division": {
      "values": [
        {
          "value": "62",
          "label": "Programmation, conseil et autres activités informatiques",
          "count": 371
        }
      ],
      "other": 0
    },
    "workforce": {
      "values": [
        { "value": "11", "label": "10 à 19 salariés", "count": 160 },
        { "value": "12", "label": "20 à 49 salariés", "count": 134 },
        { "value": "21", "label": "50 à 99 salariés", "count": 45 }
      ],
      "other": 32
    },
    "legal_form": {
      "values": [
        { "value": "5710", "label": "SAS, société par actions simplifiée", "count": 319 },
        {
          "value": "5499",
          "label": "Société à responsabilité limitée (sans autre indication)",
          "count": 41
        },
        { "value": "5599", "label": "SA à conseil d'administration (s.a.i.)", "count": 4 }
      ],
      "other": 7
    }
  },
  "sample": [
    {
      "registry_number": "847831690",
      "name": "PROMY",
      "legal_form": { "code": "5710", "label": "SAS, société par actions simplifiée" },
      "registered_on": "2018-12-07",
      "activity": {
        "code": "62.01Z",
        "scheme": "naf2008",
        "label": "Programmation informatique"
      },
      "workforce": { "code": "11", "label": "10 à 19 salariés", "year": 2023 },
      "size_category": { "code": "PME", "label": "Petite ou moyenne entreprise", "year": 2023 },
      "head_office_address": {
        "address": "30 AVENUE MARECHAL FOCH",
        "postal_code": "69006",
        "city": "LYON",
        "departement": "69"
      },
      "sources": {
        "registry": "insee_sirene",
        "data_updated_at": "2025-12-06T08:51:12Z",
        "head_office_data_updated_at": "2025-09-30T14:47:09Z",
        "legal": null
      }
    }
  ],
  "prospecting": {
    "include_sole_traders": false,
    "acknowledgement": null,
    "lists_partially_disclosed": false,
    "notice": "Built from INSEE Sirene. It does not reflect an opposition to prospecting recorded only in the RNE (diffusionCommerciale), which Firmus does not read yet. Partially disclosed companies are counted but never listed."
  },
  "sources": {
    "registry": "insee_sirene",
    "legal": null,
    "index": {
      "built_at": "2026-11-01T16:10:38Z",
      "patched_at": null,
      "fed_through": "2026-11-01T15:58:35Z"
    },
    "relative_to": "2026-11-01"
  }
}

A segment that matches nothing is still a 200, with count: 0, empty facet values and an empty sample — never a 404.

The filters

A closed list. Values within one filter are ORed, filters are ANDed, a filter left out is open, and "filters": {} is the whole active registry. Lists hold at most 100 values. An unknown filter, an unknown body field or a value a filter does not accept refuses the whole request with 400 invalid_request, and message names the filter and what it accepts — a misspelt filter is never ignored, because the count would then answer a question you did not ask.

FilterValue
activityNAF divisions ("62") and NAF codes ("62.01Z" or "6201Z"), mixed
departementThe head office's département: "75", "2A", "974"
communeThe head office's INSEE commune code, not its postal code: "31555"
postal_codeThe head office's postal code, five digits
workforce{ "from": "11", "to": "22" }, INSEE workforce bands, inclusive, either bound optional
size_category"PME", "ETI", "GE"
legal_formINSEE legal forms, four digits ("5710"), and their two-digit categories ("57"), mixed
registered_on{ "from": "2024-01-01", "to": "2024-12-31" }, YYYY-MM-DD, inclusive, either bound optional
head_office_moved_within_daysThe head office moved in the last N days, 1 to 3 650
workforce_up_within_daysThe workforce band went up in the last N days, 1 to 3 650
proceeding_opentrue: an insolvency proceeding is open, from the BODACC; false: none is

The workforce bands are 00 (none), 01 (1–2), 02 (3–5), 03 (6–9), 11 (10–19), 12 (20–49), 21 (50–99), 22 (100–199), 31 (200–249), 32 (250–499), 41 (500–999), 42 (1 000–1 999), 51 (2 000–4 999), 52 (5 000–9 999) and 53 (10 000 and more). A company whose band is not filled in, NN, never matches a workforce filter, and that is most companies: run the segment without workforce first and read the workforce facet, whose NN value is how many the filter would leave out.

In Paris, Lyon and Marseille the head office's commune is its arrondissement: Paris is 75101 to 75120, Lyon 69381 to 69389, Marseille 13201 to 13216. The city's own code (75056, 69123, 13055) matches almost nothing, so send the arrondissements, or departement.

Natural language is not read. "IT services in Lyon" is yours to turn into codes, and the answer's filters says back how each value was read: a NAF division with level: "division", a code with level: "code", a legal-form category with level: "category", each with its INSEE label, a workforce bound with its band's label, and a window with the day it starts from, { "days": 182, "since": "2026-05-03" }. Show it to whoever asked, so a misreading can be corrected. Labels are INSEE's, in French. A code the nomenclature does not hold says label: null — a NAF rév. 1 code still found on old companies (51.1T), a division NAF rév. 2 leaves unused (04), a retired legal form — so read label as nullable. A division is the first two characters of the code whatever its revision, so "51" also holds NAF rév. 1 wholesalers (51.1T) under the NAF rév. 2 label "Transports aériens"; filter on full codes when the revision matters.

Windows count from the day the segment runs, in Paris, given as sources.relative_to. A saved segment stores 182, not a date, so "moved in the last six months" slides with time.

The answer

  • count is exact: every active legal entity that matches, partially disclosed units and sole traders included.
  • exportable_count is how many of them may be listed: what the sample is drawn from and what an export would write. It leaves out every partially disclosed unit and, unless you ask for them, every sole trader (below).
  • facets split count by département, NAF division (activity_division), workforce band and legal form: the top facet_limit values by count (10 by default, 1 to 100) and other, what those values leave out. Each facet's values and other add up to count. A missing value is a value like any other, so value can be null. label is null on every departement value, on a null value, and on any value INSEE does not label.
  • sample is at most ten companies, spread across the segment rather than its oldest registrations, and the same ten until the data changes. Each carries name, legal_form, registered_on, activity, workforce, size_category and head_office_address, as enrich returns them. sources.data_updated_at is the registry's own timestamp for the company's record, and head_office_data_updated_at the one for its head office — not the time Firmus imported either.
  • sources names the registry, and the BODACC under legal ("bodacc") when proceeding_open is used. index.fed_through is the instant the data behind the count was read: a change Firmus received after it is not counted yet. built_at and patched_at date the last monthly rebuild and the last daily update; patched_at is null until the first daily update after a rebuild.
  • prospecting says what the sample and an export were allowed to list. Repeat prospecting.notice wherever you show the companies.

What a listing may show

The sample, an export, and anything else that lists the companies of a segment follow three rules. Counts and facets are not a listing and follow none of them.

  1. A partially disclosed company is never listed — not in a sample, not in an export — whatever its legal form: the person behind it asked for parts of the record to be withheld from public reuse. A company whose head office is partially disclosed counts as one: it is in count and never in exportable_count, the sample or an export. prospecting.lists_partially_disclosed is always false. A company that becomes partially disclosed after the segment was saved leaves it at once. See masked records.
  2. Sole traders are not listed by default. A sole trader (legal form 1000) is a natural person, and on the whole registry they are nearly half of count. To list them, send include_sole_traders: true with acknowledgement: "sole-traders-2026-11-01" and save: true (below).
  3. The registry's opposition to prospecting is not read. Segments are built from INSEE Sirene and do not reflect an opposition recorded only in the RNE (diffusionCommerciale). prospecting.notice says so in every answer, and the first line of every export repeats it.

Including sole traders

The acknowledgement states that your organization is the controller of any prospecting of the sole traders the segment lists: it informs each of them under article 14 of the GDPR when it first uses their data, and honours their opposition to prospecting. Sending include_sole_traders: true without it, or with another version, is refused rather than answered with fewer companies, and message quotes the text and names the version:

{
  "error": {
    "status": 400,
    "code": "invalid_request",
    "message": "`include_sole_traders` lists natural persons, and needs the acknowledgement `sole-traders-2026-11-01` in `acknowledgement`: \"The customer is the controller of any prospecting of the sole traders (entrepreneurs individuels) this segment lists, who are natural persons: it informs each of them under article 14 of the GDPR when it first uses their data, and it honours their opposition to prospecting.\"",
    "documentation_url": "https://docs.firmus.sh/reference/errors#invalid_request"
  }
}

The segment must also be saved, since the acknowledgement is stored with it — which key or Claude connection gave it, when, and which version — and repeated as prospecting.acknowledgement in every answer that runs it and at the top of every export. Without save: true the request is 400 invalid_request. A new wording will be a new version; the version is part of what you store on your side.

Save it

save: true stores the segment's name (up to 200 characters; "Untitled segment" without one) and its filters as normalized — "6201Z" becomes "62.01Z" — and answers 201 Created, with the segment's URL in Location and the stored segment under segment:

curl -s -X POST https://api.firmus.sh/v1/fr/segments \
  -H "Authorization: Bearer $FIRMUS_KEY" \
  -H "Content-Type: application/json" \
  -d '{"filters": {"activity": ["62"], "departement": ["69"]}, "name": "Lyon software", "save": true}'

segment carries id, name, filters, include_sole_traders, acknowledgement (null, or its version, text — the wording of that version, which is never edited — acknowledged_at and acknowledged_by), created_at and updated_at. A saved segment is not edited: delete it and save a new one.

Saved segments are a number your plan holds, not a monthly volume: 3 on Free, 100 on Pro, 1 000 on Scale. A save beyond it is refused with 402 quota_exceeded and saves nothing; it carries no Retry-After, because deleting a segment frees its place, and no date does. Running a segment without save is never refused for it.

A saved segment can also be followed from a watchlist, which is then told which companies enter it, and on request which leave it, after each daily update of the index: see follow a segment.

Errors

  • 400 invalid_request — an unknown filter or body field, a value a filter does not accept, a facet_limit outside 1 to 100, sole traders without the acknowledgement or without save, or a body that is not JSON. message says which. Nothing is counted.
  • 402 quota_exceeded — a save beyond the plan's saved segments, without Retry-After; or, on Free, the month's lookups are spent, with Retry-After.
  • 403 public_key_forbidden — a publishable fk_pub key holding read; one without it gets 403 insufficient_scope.
  • 404 not_found — a country other than fr.
  • 503 segment_index_unavailable — this server cannot count segments yet. Nothing is counted; retry later.

Next

  • Export a segment — every company in a saved segment, as a CSV.
  • Errors — every code above, and how to tell a refusal from an outage.
POST/v1/{country_code}/segmentsScope read

Parameters

ParameterInTypeRequiredExample
country_codepathstringYesfr

Request

bash
curl -X POST -H "Authorization: Bearer $FIRMUS_KEY" \
  -H "Content-Type: application/json" \
  -d '{"filters":{"activity":["62"],"departement":["69"],"workforce":{"from":"11"}},"facet_limit":3}' \
  "https://api.firmus.sh/v1/fr/segments"

Fields

  • segmentunspecifiednullable
  • filtersobject
    • activityobject[]optional
      • []objectoptional
        • codestring
        • levelstring
        • labelstringnullable
    • departementstring[]optional
      • []stringoptional
    • workforceobjectoptional
      • fromobject
        • codestring
        • labelstring
      • toobjectnullable
        • codestring
        • labelstring
    • proceeding_openbooleanoptional
    • communestring[]optional
      • []stringoptional
    • postal_codestring[]optional
      • []stringoptional
    • size_categoryobject[]optional
      • []objectoptional
        • codestring
        • labelstring
    • legal_formobject[]optional
      • []objectoptional
        • codestring
        • levelstring
        • labelstringnullable
    • registered_onobjectoptional
      • fromstring
      • tostring
    • head_office_moved_within_daysobjectoptional
      • daysinteger
      • sincestring
    • workforce_up_within_daysobjectoptional
      • daysinteger
      • sincestring
  • countinteger
  • exportable_countinteger
  • facetsobject
    • departementobject
      • valuesobject[]
        • []objectoptional
          • valuestringnullable
          • labelunspecifiednullable
          • countinteger
      • otherinteger
    • activity_divisionobject
      • valuesobject[]
        • []objectoptional
          • valuestringnullable
          • labelstringnullable
          • countinteger
      • otherinteger
    • workforceobject
      • valuesobject[]
        • []objectoptional
          • valuestringnullable
          • labelstringnullable
          • countinteger
      • otherinteger
    • legal_formobject
      • valuesobject[]
        • []objectoptional
          • valuestringnullable
          • labelstringnullable
          • countinteger
      • otherinteger
  • sampleobject[]
    • []objectoptional
      • registry_numberstring
      • namestring
      • legal_formobject
        • codestringnullable
        • labelstringnullable
      • registered_onstringnullable
      • activityobject
        • codestringnullable
        • schemestringnullable
        • labelstringnullable
      • workforceobject
        • codestringnullable
        • labelstringnullable
        • yearintegernullable
      • size_categoryobject
        • codestringnullable
        • labelstringnullable
        • yearintegernullable
      • head_office_addressobject
        • addressstringnullable
        • postal_codestringnullable
        • citystringnullable
        • departementstringnullable
      • sourcesobject
        • registrystring
        • data_updated_atstringnullable
        • head_office_data_updated_atstringnullable
        • legalunspecifiednullable
  • prospectingobject
    • include_sole_tradersboolean
    • acknowledgementunspecifiednullable
    • lists_partially_disclosedboolean
    • noticestring
  • sourcesobject
    • registrystring
    • legalstringnullable
    • indexobject
      • built_atstring
      • patched_atstringnullable
      • fed_throughstring
    • relative_tostring

Responses

Counts the active companies matching explicit filters — activity (NAF divisions or codes), geography (département, commune, postal code), workforce band range, size category, legal form, registration date range, and the event windows (`head_office_moved_within_days`, `workforce_up_within_days`, `proceeding_open`) — and answers with the filters as interpreted, the exact count, four facets (département, NAF division, workforce band, legal form; the top `facet_limit`), and a sample of at most ten companies with their sources and dates. Partially disclosed companies are counted but never listed; sole traders are listed only with `include_sole_traders` and the acknowledgement, on a saved segment. `save: true` stores it (201) for GET, export and alerts. One call.

{
  "segment": null,
  "filters": {
    "activity": [
      {
        "code": "62",
        "level": "division",
        "label": "Programmation, conseil et autres activités informatiques"
      }
    ],
    "departement": [
      "75",
      "69"
    ],
    "workforce": {
      "from": {
        "code": "00",
        "label": "0 salarié"
      },
      "to": null
    }
  },
  "count": 4,
  "exportable_count": 2,
  "facets": {
    "departement": {
      "values": [
        {
          "value": "75",
          "label": null,
          "count": 3
        },
        {
          "value": "69",
          "label": null,
          "count": 1
        }
      ],
      "other": 0
    },
    "activity_division": {
      "values": [
        {
          "value": "62",
          "label": "Programmation, conseil et autres activités informatiques",
          "count": 4
        }
      ],
      "other": 0
    },
    "workforce": {
      "values": [
        {
          "value": "11",
          "label": "10 à 19 salariés",
          "count": 2
        },
        {
          "value": "00",
          "label": "0 salarié",
          "count": 1
        },
        {
          "value": "21",
          "label": "50 à 99 salariés",
          "count": 1
        }
      ],
      "other": 0
    },
    "legal_form": {
      "values": [
        {
          "value": "5710",
          "label": "SAS, société par actions simplifiée",
          "count": 3
        },
        {
          "value": "1000",
          "label": "Entrepreneur individuel",
          "count": 1
        }
      ],
      "other": 0
    }
  },
  "sample": [
    {
      "registry_number": "100000017",
      "name": "BETA CONSEIL",
      "legal_form": {
        "code": "5710",
        "label": "SAS, société par actions simplifiée"
      },
      "registered_on": "2020-03-02",
      "activity": {
        "code": "62.02A",
        "scheme": "naf2008",
        "label": "Conseil en systèmes et logiciels informatiques"
      },
      "workforce": {
        "code": "21",
        "label": "50 à 99 salariés",
        "year": 2023
      },
      "size_category": {
        "code": "PME",
        "label": "Petite ou moyenne entreprise",
        "year": 2023
      },
      "head_office_address": {
        "address": "2 PLACE BELLECOUR",
        "postal_code": "69002",
        "city": "LYON",
        "departement": "69"
      },
      "sources": {
        "registry": "insee_sirene",
        "data_updated_at": "2026-10-01T00:00:00Z",
        "head_office_data_updated_at": "2026-10-01T00:00:00Z",
        "legal": null
      }
    },
    {
      "registry_number": "100000009",
      "name": "ALPHA LOGICIEL",
      "legal_form": {
        "code": "5710",
        "label": "SAS, société par actions simplifiée"
      },
      "registered_on": "2020-03-02",
      "activity": {
        "code": "62.01Z",
        "scheme": "naf2008",
        "label": "Programmation informatique"
      },
      "workforce": {
        "code": "11",
        "label": "10 à 19 salariés",
        "year": 2023
      },
      "size_category": {
        "code": "PME",
        "label": "Petite ou moyenne entreprise",
        "year": 2023
      },
      "head_office_address": {
        "address": "1 RUE DE LA PAIX",
        "postal_code": "75008",
        "city": "PARIS",
        "departement": "75"
      },
      "sources": {
        "registry": "insee_sirene",
        "data_updated_at": "2026-10-01T00:00:00Z",
        "head_office_data_updated_at": "2026-10-01T00:00:00Z",
        "legal": null
      }
    }
  ],
  "prospecting": {
    "include_sole_traders": false,
    "acknowledgement": null,
    "lists_partially_disclosed": false,
    "notice": "Built from INSEE Sirene. It does not reflect an opposition to prospecting recorded only in the RNE (diffusionCommerciale), which Firmus does not read yet. Partially disclosed companies are counted but never listed."
  },
  "sources": {
    "registry": "insee_sirene",
    "legal": null,
    "index": {
      "built_at": "2026-11-01T03:00:00Z",
      "patched_at": "2026-11-01T08:47:00Z",
      "fed_through": "2026-11-01T08:46:12Z"
    },
    "relative_to": "2026-11-01"
  }
}