# GIPOD History: Antwerp roadworks and date changes (`snenenenene/gipod-history`) Actor

GIPOD roadworks and street occupations around an Antwerp address, with first and last seen dates and every change to start, end or status since a given day. One result per work. Suggested price: $0.005 per work returned.

- **URL**: https://apify.com/snenenenene/gipod-history.md
- **Developed by:** [Senne Bels](https://apify.com/snenenenene) (community)
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

Pay per usage

This Actor is paid per platform usage. The Actor is free to use, and you only pay for the Apify platform usage, which gets cheaper the higher subscription plan you have.

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

## 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

## GIPOD History: Antwerp roadworks and date changes

GIPOD is the Flemish register of roadworks and other uses of the public road (markets, events, building sites, parking bans). Its map service answers with what is registered now. This actor answers with what was registered around an address over time: every work and street occupation within up to 1000 m, when it was first and last seen, and every change to its published start date, end date or status since a day you pick.

The data comes from the [Stadiq](https://stadiq.app/developers) GIPOD archive, which has read GIPOD daily since 11 April 2026.

### Input

| Field | Required | Description |
| --- | --- | --- |
| `address` | one of address or lat/lng | A street address in Belgium, e.g. `Lange Lozanastraat 142, 2018 Antwerpen`. |
| `lat`, `lng` | one of address or lat/lng | WGS84 coordinates. Used instead of the address when both are given. |
| `radiusMeters` | no | Radius around the point, 1 to 1000. Default 500. |
| `since` | no | First day to include, `YYYY-MM-DD`. Default: the start of the archive. |
| `until` | no | Last day to include, `YYYY-MM-DD`. Default: today. |
| `maxResults` | no | Stop after this many works. Default 200. |

### Output

One dataset item per work, nearest first:

```json
{
  "gipod_id": "12350353",
  "title": "Gemengde markt\nDesguinlei",
  "kind": "occupation",
  "status": { "published": "Lopende", "mapped": "unknown" },
  "first_seen": "2026-04-11",
  "last_seen": "2026-10-24",
  "days_seen": 194,
  "start": "2026-10-23T09:30:00Z",
  "end": "2027-04-23T14:30:00Z",
  "revisions": [
    { "seen_at": "2026-09-04", "field": "end", "from": "2027-02-26T15:30:00Z", "to": "2027-03-05T15:30:00Z" },
    { "seen_at": "2026-09-06", "field": "start", "from": "2026-09-04T09:30:00Z", "to": "2026-09-11T09:30:00Z" }
  ],
  "revision_count": 15,
  "distance_m": 777,
  "lat": 51.197357115,
  "lng": 4.394453540000001,
  "query": { "lat": 51.1931, "lng": 4.4033, "address": null, "radius_m": 1000, "since": "2026-09-01", "until": "2026-11-08" },
  "coverage_state": "gaps",
  "source": "GIPOD",
  "licence": "Modellicentie Gratis Hergebruik Vlaanderen v1.0",
  "attribution": "Bevat overheidsinformatie, verkregen onder de Modellicentie Gratis Hergebruik Vlaanderen v1.0 (bron: Digitaal Vlaanderen, GIPOD)."
}
```

(Abridged: this market had 15 revisions in the window; two are shown.)

- `kind` is `work` for groundworks and `occupation` for other uses of the street, such as a weekly market.
- `status.published` is GIPOD's own status in Dutch. `status.mapped` is that status and the dates mapped to `active`, `planned`, `ended` or `unknown` for today. An occupation inside its date window is `unknown`, never `active`.
- `start` and `end` are as published in the latest capture, in UTC.
- `revisions` lists every change to start, end or status seen inside your window, oldest first. Weekly markets roll their dates forward every week, and that shows up here.

The run also writes a `COVERAGE` record to the default key-value store. Read it before you read the dataset.

### Coverage and its limits

- **Area**: Antwerp and 15 km around its centre (51.2194, 4.4025). A point whose radius reaches past that circle fails with `outside_archive_area` instead of returning an empty list.
- **Time**: from 11 April 2026. Nothing before the first capture is known; `COVERAGE.coverage.window_starts_before_archive` says when your window starts earlier.
- **Missing days**: the archive has gaps. `COVERAGE.coverage.missing_days` lists every day in your window that was not captured. A work can have changed on a missing day; the change then shows on the next captured day.
- **Truncated reads**: GIPOD caps a single read, so on some days it returned only part of the register. `partial_capture_days` counts them. A work can be absent on such a day without having ended.
- **Live check**: each run also reads GIPOD live for the same point. `live_gipod.not_yet_archived` counts works GIPOD lists now that the archive has not captured.
- **Unavailable is not empty**: if no day of your window was captured, the run fails with a message and charges nothing for results. It never reports a quiet street it did not look at.

### Licence and attribution

The data is public-sector information from GIPOD, published by Digitaal Vlaanderen under the [Modellicentie Gratis Hergebruik Vlaanderen v1.0](https://www.vlaanderen.be/datavindplaats/catalogus/gipod-geplande-mobiliteitshinder-publieke-informatie-ldes). Commercial reuse is allowed with attribution. Every item carries the attribution text; show it wherever you republish the data.

### Pricing

Pay per event: one `work-returned` event per dataset item. Suggested price: **$0.005 per work**. For scale: on 8 November 2026 GIPOD listed 18 registrations within 500 m of the Desguinlei and 77 within 1000 m. The run stops when your spending limit is reached and pushes nothing it cannot charge for.

### Publishing (for the actor owner)

1. Create or sign in to an Apify account.
2. `npx apify-cli login` and paste the API token from Apify Console, Settings, API & Integrations.
3. Store the Stadiq API key as a CLI secret (a key on the `api` plan, created at https://stadiq.app/developers):
   `npx apify-cli secrets add stadiqApiKey sq_live_…`
   `.actor/actor.json` maps it to the `STADIQ_API_KEY` environment variable, and `apify push` stores it on the actor as a secret value that users cannot read.
4. From this directory: `npx apify-cli push`.
5. In Apify Console, open the actor, Publication: set the pricing model to pay per event, add the event `work-returned` (title "Work returned", description "One GIPOD work in the dataset") at the price you choose, fill in the Store details, and publish.
6. Run it once with the prefilled input and check the dataset and the `COVERAGE` record.

To rotate the key: `npx apify-cli secrets add stadiqApiKey <new key>` (remove the old one first with `secrets rm`), then `npx apify-cli push` again, or edit the secret under Source, Environment variables in Console.

### Local test

```sh
npm install
npm test
```

The test runs the actor's `run()` against a mocked Stadiq API with a fake Apify `Actor`, and checks paging, one charge per pushed item, the spending-limit stop and the unavailable case.

# Actor input Schema

## `address` (type: `string`):

A street address in or near Antwerp, e.g. "Lange Lozanastraat 142, 2018 Antwerpen". Ignored when latitude and longitude are given.

## `lat` (type: `number`):

Latitude of the point (WGS84). Use together with longitude instead of an address.

## `lng` (type: `number`):

Longitude of the point (WGS84).

## `radiusMeters` (type: `integer`):

How far around the point to look, up to 1000 m.

## `since` (type: `string`):

First day to include, as YYYY-MM-DD. Works seen in the archive on or after this day are returned, with the changes seen from this day on. Leave empty to start at the beginning of the archive.

## `until` (type: `string`):

Last day to include, as YYYY-MM-DD. Defaults to today.

## `maxResults` (type: `integer`):

Stop after this many works. Each work returned is one charged event.

## Actor input object example

```json
{
  "address": "Lange Lozanastraat 142, 2018 Antwerpen",
  "radiusMeters": 500,
  "maxResults": 200
}
```

# Actor output Schema

## `works` (type: `string`):

One item per GIPOD work: dates, status, first and last seen, and every revision.

# 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 = {
    "address": "Lange Lozanastraat 142, 2018 Antwerpen"
};

// Run the Actor and wait for it to finish
const run = await client.actor("snenenenene/gipod-history").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 = { "address": "Lange Lozanastraat 142, 2018 Antwerpen" }

# Run the Actor and wait for it to finish
run = client.actor("snenenenene/gipod-history").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 '{
  "address": "Lange Lozanastraat 142, 2018 Antwerpen"
}' |
apify call snenenenene/gipod-history --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,snenenenene/gipod-history"
        }
    }
}
```

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/FiWZAagJEV9oVf8Dj/builds/1OZxCAkk9g3cfpR9D/openapi.json
