# Armenia Public Contracts Weekly Changes (`reestri/am-contracts-weekly`) Actor

What changed in Armenia's public procurement this week: new contracts with total value, first-time suppliers, the 15 biggest new awards and the largest single-source award. From the official contracts registry (PPCM), diffed weekly. No input needed.

- **URL**: https://apify.com/reestri/am-contracts-weekly.md
- **Developed by:** [Soso Pkhakadze](https://apify.com/reestri) (community)
- **Categories:** Business, Automation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / weekly summary

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

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

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## Armenia Public Contracts Weekly Changes

What changed in Armenia's public procurement this week, in one run with no input:
how many contracts appeared in the registry since the previous snapshot, their
combined value in AMD, how many suppliers won a state contract for the first time,
the 15 biggest awards signed in the last 90 days, the 15 biggest new entries overall,
and the largest non-competitive (single-source) award. Built on the official
contracts registry (PPCM, Ministry of Finance / armeps.am), which we index weekly;
each run compares the fresh snapshot against the previous one, so nothing is
estimated and every number comes from the registry itself.

### What "new" means

A new contract is one whose registry id appeared in our index since the previous
weekly snapshot. Read that carefully: it is not the same as "signed this week". The
registry publishes with delay, sometimes by years, and a weekly walk of the registry
is not always complete. So the new set mixes three things:

- contracts the registry published this week (most of them signed recently),
- older contracts published late by the buyer (backfill),
- contracts that exist in the registry but the previous walk failed to fetch.

The summary record makes these distinguishable instead of hiding them:

- `signedAtHistogram` buckets the new contracts by signing date relative to the
  snapshot: `last30Days` (0 to 30 days before), `last90Days` (31 to 90), `older`
  (more than 90 days), `unknown` (no usable date). A large `older` bucket means
  backfill or a walk gap, not a spending spike.
- Every contract entry carries `likelyBackfill: true` when it was signed more than
  90 days before the snapshot.
- `topNewContractsRecent` is the top 15 by value among contracts signed in the last
  90 days. Lead with it; `topNewContracts` (the 15 biggest new entries regardless of
  signing date) is kept for completeness.
- `removedContracts` counts ids that were in the previous snapshot and are missing
  now. The registry does not delete contracts as a rule; this number is the walk gap
  on the registry side (throttled or dropped pages), and those ids usually come back
  as "new" a week later.
- `walk` says how complete the snapshot is: `totalReported` is the count the portal
  itself reports, `fetched` is how many contracts the walk indexed, `missingShare`
  is the gap as a share of the reported total. When `missingShare` is high, treat
  the week's counts as a lower bound.

### What you can do with it

- **Monitoring**: a weekly pulse on Armenian state spending for journalists,
  analysts and compliance teams, without paging the registry yourself.
- **Single-source watch**: the biggest non-competitive award is called out
  separately; these are a standard procurement red flag. Check its `likelyBackfill`
  flag before calling it this week's award.
- **New-entrant tracking**: suppliers that appear in the registry for the first
  time, a common signal in integrity screening. "First time" is relative to the
  previous snapshot, so a walk gap can inflate it; read it with `walk` in mind.
- **Joins with the register**: `supplierTaxId` and `buyerTaxId` are the same
  8-digit tax IDs used by our Armenia Company Registry and Armenia Supplier
  Public Contracts tools, so ownership and award history link cleanly.
- **AI agents**: run it on a schedule and feed the summary record to an agent.

### Input

None. Run it as is; every run returns the latest weekly change summary.

### Output

One `weekly_change` summary record per run:

```json
{
  "resultType": "weekly_change",
  "country": "AM",
  "snapshotAt": "2026-09-06T04:03:42.289Z",
  "previousSnapshotAt": "2026-08-30T04:45:48.200Z",
  "newContracts": 2321,
  "newValueAMD": 79836683490,
  "newSuppliers": 84,
  "removedContracts": 2910,
  "walk": { "totalReported": 238624, "fetched": 235570, "missingShare": 0.012798 },
  "signedAtHistogram": { "last30Days": 1180, "last90Days": 410, "older": 720, "unknown": 11 },
  "largestSingleSource": {
    "contractId": "0d5aff58-...",
    "buyer": "...",
    "supplier": "...",
    "valueAMD": 4276641552,
    "procedure": "single source",
    "signedAt": "2023-08-29",
    "singleSource": true,
    "likelyBackfill": true
  },
  "topNewContractsRecent": [ { "contractId": "...", "valueAMD": 1200000000, "signedAt": "2026-09-01", "likelyBackfill": false } ],
  "note": "A new contract is one whose registry id appeared in our index since the previous snapshot. ...",
  "evidence": { "sourceUrl": "https://armeps.am/ppcm/public/contracts/list", "registryAsOf": "2026-09-06" }
}
```

The snapshot dates, `newContracts`, `newSuppliers`, `removedContracts` and `walk`
above are the real 2026-09-06 numbers: the walk indexed 235,570 of the 238,624
contracts the portal reported, and 2,910 ids from the week before were not fetched.
The histogram and the contract entries are illustrative.

Then one `contract` record per top new contract (buyer, supplier, tax IDs, value,
procedure, signing date, single-source flag): the recent list first (`recent: true`,
up to 15), then the remaining entries of the overall top 15 (`recent: false`).
Each carries `likelyBackfill`. Finally `unavailable` if the change feed cannot be
read (the run also fails; never a negative result).

The first run after the feed is created returns `{"bootstrap": true}` instead of
a diff: there is no previous snapshot yet, and we do not fabricate one. The first
real diff arrives with the next weekly index.

### Scope and hygiene

- Source: the public contracts registry's own JSON service, indexed weekly by our
  sync job; `registryAsOf` is the snapshot date. The full list of new ids and a
  sample of removed ids are kept alongside the index; ask if you need them.
- The single-source flag is read from the registry's procedure type (purchases
  from one person); it is a procedure classification, no judgement is added.
- The registry publishes supplier emails, bank account numbers and internal staff
  identifiers; **we strip all of them at ingest** and never store them.
- Armenia has announced a new procurement platform for 2027; this tool will
  migrate when it launches.

### Pricing

Pay per event: one `week` charge of $1.00 per run, plus Apify's tiny start event. Platform
usage is included. The charge happens only after the weekly feed was read, so a run
that returns `unavailable` costs nothing beyond the start event. If you set a maximum
cost per run below $1.00, the run returns one `charge_limit_reached` record instead of
the summary and nothing is charged for it.

# Actor input Schema

## Actor input object example

```json
{}
```

# Actor output Schema

## `changes` (type: `string`):

One `weekly_change` summary record (new contracts, value, first-time suppliers, removed ids, walk completeness, signing-date histogram, largest single-source award, top recent awards) plus one `contract` record per top new contract with a likelyBackfill flag, or `unavailable`, each with an evidence block.

# 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 = {};

// Run the Actor and wait for it to finish
const run = await client.actor("reestri/am-contracts-weekly").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 = {}

# Run the Actor and wait for it to finish
run = client.actor("reestri/am-contracts-weekly").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 '{}' |
apify call reestri/am-contracts-weekly --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,reestri/am-contracts-weekly"
        }
    }
}
```

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/YY210E8fSL3ws5PDj/builds/hyuwsFWS9i6wLd8Hx/openapi.json
