# Changelog of Peppol Participant Lookup – Reachability Monitor (`lwsdjfls/peppol-participant-monitor`) Actor

- **URL**: https://apify.com/lwsdjfls/peppol-participant-monitor/changelog.md
- **Full Actor documentation**: https://apify.com/lwsdjfls/peppol-participant-monitor.md

## Changelog

### 0.1 (2026-09-17)

- Bulk Peppol participant lookup from KvK, VAT, KBO/BCE, GLN, SIREN/SIRET and other company identifiers, with check-digit validation and both Belgian schemes checked.
- Reachability from the live network: SML (DNS) registration, SMP document types and processes, and the receiving access point (provider and seat ID) from its certificate.
- Registered name, country and registration date from the Peppol Directory, queried at no more than 2 requests per second.
- Monitor mode: changes for followed participants (reachable, unreachable, document types, access point, name) and new registrations per country, with pending registrations re-checked until they are reachable.
- Each new registration is charged together with its own record, so a run that stops partway through a registration day (spending limit, `maxLookupsPerRun` + `maxNewRegistrationsPerRun` or a failed dataset write) charges only the registrations it delivered.
- The run log says how many identifiers a run did not check because `maxLookupsPerRun` or your spending limit was reached (every run checks identifiers in list order), and when registrations were left unchecked, which a later run picks up only while their registration day is within `lookbackDays`.
- GDPR: contact persons, e-mail addresses, phone numbers, addresses, free text and technical contacts are never collected.
- A run with nothing to do says which field to fill in for the mode it is in: identifiers in lookup mode, identifiers or countries in monitor mode. The empty `required` list in the input schema is gone; neither field can be required, because monitor mode works on countries alone.
- README corrected: only KBO/BCE and Belgian VAT numbers, GLN and SIREN are checked by check digit, so a well-formed typo in another type is looked up and charged; for a Belgian number the second scheme is tried only when the first is not registered, and `participantIdsChecked` lists both either way. The unsourced Belgian and French e-invoicing dates give way to a general statement, and the Directory's limits, the registration peak, the lookup timing and the provider-name remark are now stated as what the Actor does, without unsourced figures. Added: the Actor start in the pricing example, the worst case at the default limits ($10.00005 for a lookup run, $58.00005 for a monitor run), charged business card changes that need no lookup, where to set Max cost per run, two limitations (each identifier type is looked up only under its own scheme; what `reachable` does not check) and the date the README was last verified.
- A short DNS outage no longer fails the run. When the lookups of the well-known participants checked before the first identifier fail with an error, the run tries them again after 5, 10, 20, 40, 60 and 60 seconds, starts no try later than 200 seconds after the first and never waits more than half of the time it has left, and logs each wait. When they all answer "not registered", it still stops at once. Either way it stops before the first lookup.
- A monitor run that follows countries and no identifiers, and could load none of its registration days, waits for the Peppol Directory once, for up to 10 minutes (less when its timeout is near), with the first day whose search failed on a temporary error, and when that day loads, searches the other such days once more. Such a run used to fail as soon as every day's search had used its four attempts. Every day is searched first, as before, and a run in which a day loads does not wait, so the wait never takes the time of the days that load.
- A run that gets close to its timeout stops starting lookups and delivers what it has, instead of timing out with nothing delivered. Records are delivered after the lookups, so a lookup, or a registration day's search, starts only while the time left covers delivering every record so far and every record the work in flight can bring (0.1 seconds each, the delivery time core measured on Apify), plus what the lookup or search is expected to take: the average of those this run has timed, but never more than one attempt of each request it makes one after another (90 seconds for a lookup, 30 for a search). Before the first search, a search is reckoned at the average of the lookups the run has timed (a lookup asks the SMP and the Directory one request after another), so a run whose followed identifiers end shortly before its timeout still searches its countries' registration days; only a run that has timed nothing yet reckons a lookup at 90 seconds and a search at 30. So a lookup that ran through its retries, such as one against an SMP that does not answer (about two minutes before it ends `lookup-failed`), does not stop the lookups after it. A run whose work and its delivery fit before its timeout therefore delivers exactly what it delivers without one. A registration day's renamed and removed registrations, known once its search is back, need no lookup; the day goes on only while their records can be delivered, and is otherwise left for a later run. A day the Directory lists only in part reports no removals, so its stored registrations missing from the page take no delivery time. In lookup mode each identifier the run did not reach gets a free `lookup-failed` record whose `statusReason` says to submit it again, for as long as the run can still deliver those records; the identifiers after that are not in the dataset. Identifiers past `maxLookupsPerRun` get no record, as the cap leaves them out, and the warning counts them with the cap, not with the timeout. In monitor mode the identifiers the run did not reach keep their last known state, and registrations and registration days it did not reach are left for later runs and never reported as removed. Such a run succeeds, and its `RUN_SUMMARY` says `partial`, also when a wait for the Directory used up the time to search the other days again; the identifiers it did not check are counted in its `leftOut` and its status message. The log says how many and what to do. A run with a one-hour timeout therefore checks at most about 5,800 registered participants in lookup mode or in a first monitor run, and nearly 7,000 in a later monitor run that finds few changes; the README and the `maxLookupsPerRun` description said lists of up to about 5,000 fit.
- The identifiers `maxLookupsPerRun` or the spending limit left out are counted in the run's status message and in `leftOut` of `RUN_SUMMARY`; the identifier whose lookup the cap refused no longer counts as an incomplete scope. Records and charges are unchanged.
- The wait for the Peppol Directory in a monitor run without identifiers leaves the time to deliver what the run has collected.
- Default run timeout 24 hours (`runTimeoutSecs` in `store/listing.json`, written to Apify Console by store-sync), stated in the README with the note that a run can be given another timeout in the run options. The largest input the input schema allows, at the Actor's own pace: 100,000 identifier lookups at the Directory's 2 requests per second (50,000 s), 40 countries × 14 registration days of Directory searches at the same pace (280 s), 50,000 registration lookups of at least two SMP requests each at 6 requests per second per SMP host (16,667 s), and 150,000 records at 0.1 s (15,000 s): 81,947 s, plus 10% is 90,141 s, 25.04 hours, so the ceiling of 24 hours applies. Lookup mode alone takes 100,000 × (0.5 + 0.1) s = 60,000 s, about 17 hours.
- Monitor name (`stateKey`) is a secret input: stored encrypted, like the webhook URL, because it often names a customer. Apify checks no pattern on a secret field, so any text is now accepted instead of failing the run: a key of letters, digits, dashes and underscores keeps the state it had, other text gets a state of its own, spaces around it are ignored and a blank one counts as none.
- Store discounts: Apify's paid plans pay less for every event except the Actor start, 5% on the Bronze tier, 10% on Silver and 15% on Gold and higher. The prices in the README are the list prices, which the Free plan pays.
