# Indonesia SDPPI Telecom Type Approval Certificates (`a-g-d/id-sdppi`) Actor

Indonesia's SDPPI (Komdigi) telecom equipment type-approval register as English-keyed JSON: issued and revoked certificates with certificate number, issue and expiry dates, applicant, device, brand, model, manufacturer and country, filtered by keyword, brand, model, applicant, country or date.

- **URL**: https://apify.com/a-g-d/id-sdppi.md
- **Developed by:** [Aloever Dulay](https://apify.com/a-g-d) (community)
- **Categories:** E-commerce, Other
- **Stats:** 2 total users, 1 monthly users, 94.4% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 certificate records

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?

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

## Indonesia SDPPI Telecom Type-Approval Certificates Actor

Indonesia's register of **telecom equipment type-approval certificates** ("sertifikat
perangkat telekomunikasi"), issued by the SDPPI directorate of the Ministry of
Communication and Digital (Komdigi, formerly Kominfo), read from
[sertifikasi.postel.go.id](https://sertifikasi.postel.go.id/sertifikat/sertifikat-terbit)
as clean, English-keyed JSON: certificate number, issue and expiry dates, applicant
(certificate holder), device name, brand, model, manufacturer and its country.

Two public lists, 118,671 certificates on 2026-10-14:

| `list`    | Page                                 | Rows    |
| --------- | ------------------------------------ | ------- |
| `issued`  | Sertifikat Terbit (issued, in force) | 118,452 |
| `revoked` | Sertifikat Pencabutan (revoked)      | 219     |

About 35 certificates are issued per working day; the list comes newest first, so a small
run returns the latest approvals.

### Who needs this

- **Importers, distributors and marketplaces** checking that a phone, router, IoT module
  or other radio or telecom device is type-approved for Indonesia before importing or
  listing it, and under which certificate number.
- **Device makers and their Indonesian applicants** watching new approvals, competitors'
  certified models and certificates coming up for renewal (they run three years).
- **Compliance, customs and regulatory-affairs teams** matching certificate numbers on
  labels and customs documents to the regulator's register.
- **Market researchers and journalists** studying which brands, device types and
  manufacturing countries enter the Indonesian market.
- **AI agents and automations** that need a stable schema instead of a paged web page.

### Input

| Field                 | Type    | Default    | Description                                                                                                                     |
| --------------------- | ------- | ---------- | ------------------------------------------------------------------------------------------------------------------------------- |
| `list`                | string  | `"issued"` | `issued` or `revoked`.                                                                                                          |
| `keyword`             | string  | `""`       | The site's own search: certificate number, applicant, device name, brand, model or marketing name contains this text, any case. |
| `brand`               | string  | `""`       | Brand ("Merk") contains this text, any case (`xiaomi`).                                                                         |
| `model`               | string  | `""`       | Model contains this text, any case (`M2320`).                                                                                   |
| `applicant`           | string  | `""`       | Applicant (certificate holder) contains this text, any case (`erajaya`).                                                        |
| `manufacturerCountry` | string  | `""`       | Two-letter ISO code of the country of manufacture (`CN`, `VN`, `ID`).                                                           |
| `issuedSince`         | string  | `""`       | Issued on or after this date (`YYYY-MM-DD`).                                                                                    |
| `issuedBefore`        | string  | `""`       | Issued before this date (`YYYY-MM-DD`).                                                                                         |
| `expiringBefore`      | string  | `""`       | Validity ends before this date (`YYYY-MM-DD`).                                                                                  |
| `maxItems`            | integer | `100`      | Stop after this many certificates (1-50,000).                                                                                   |
| `proxyConfiguration`  | object  | no proxy   | Optional Apify Proxy, if the site is unreachable from Apify's network.                                                          |

Filters combine with AND. `keyword`, `brand`, `model` and `applicant` are applied by the
site itself (its search and its advanced filter, case-insensitive "contains"), so a run with
only those reads exactly the rows it returns. `manufacturerCountry` and the date filters are
checked on each row while the actor pages through the list newest first, 500 rows per
request.

**Order.** Newest issue first, in both lists.

**Date filters stop early.** The list is newest first, so `issuedSince: "2026-10-01"` reads
the pages down to that date and stops; the newest 1,000 certificates are about a month.
Dates are the Indonesian calendar dates the site publishes.

### Output

One dataset item per certificate row. Keys are English; names are kept as the register
publishes them with the whitespace tidied, timestamps are kept exactly as published,
`isValid` is the site's "berlaku" (in force) flag. The Output tab on this page documents
every field, with one table view per list.

A real issued certificate (2026-10-14):

```json
{
  "list": "issued",
  "certificateNumber": "127598/DJID/2026",
  "issuedAt": "2026-10-13T22:55:01.817882Z",
  "expiresAt": "2029-10-13T22:55:01.815927Z",
  "isValid": true,
  "applicant": "PT TIGA-TIGA NUSANTARA",
  "applicationId": 178454,
  "legalBasis": "KEPMEN KOMINFO NOMOR 60 TAHUN 2022",
  "manufacturer": "ALPHA NETWORKS VIET NAM CO., LTD",
  "manufacturerCountryCode": "VN",
  "manufacturerCountry": "Vietnam",
  "deviceName": "Ethernet Switch",
  "brand": "Extreme Networks",
  "marketingName": "Extreme Networks",
  "model": "5420M-48W-4YE",
  "updatedAt": "2026-10-13T22:55:01.851889Z",
  "sourceUrl": "https://sertifikasi.postel.go.id/sertifikat/sertifikat-terbit",
  "fetchedAt": "2026-10-13T22:17:00.000Z"
}
```

A real revoked certificate:

```json
{
  "list": "revoked",
  "certificateNumber": "112579/DJID/2025",
  "issuedAt": "2025-07-21T10:27:03.681843Z",
  "expiresAt": "2028-07-21T10:27:03.680024Z",
  "isValid": false,
  "applicant": "PT MULTI PRIMA SOLUSI",
  "applicationId": 162563,
  "legalBasis": "KEPMEN KOMINFO NOMOR 60 TAHUN 2022",
  "manufacturer": "SHENZHEN FOUR-FAITH COMMUNICATION TECHNOLOGY CO., LTD",
  "manufacturerCountryCode": "CN",
  "manufacturerCountry": "China",
  "deviceName": "Router",
  "brand": "Four-Faith",
  "marketingName": "Four-Faith",
  "model": "F-NR330",
  "updatedAt": "2025-08-27T14:46:04.456129Z",
  "sourceUrl": "https://sertifikasi.postel.go.id/sertifikat/sertifikat-pencabutan",
  "fetchedAt": "2026-10-13T22:17:00.000Z"
}
```

Notes on the fields:

- **Timestamps** are published by the site in ISO-8601 with a `Z` suffix and microseconds,
  and kept that way. Their hours fall in Indonesian office hours, so they read as Indonesian
  western time (WIB, UTC+7) despite the suffix; the date part is the Indonesian date.
- **`isValid`** is the site's own flag and is separate from the list: a few rows of the
  issued list carry `false` and a few rows of the revoked list carry `true` (4 of 219 on
  2026-10-14, all past their expiry). The actor outputs both as published.
- **`brand` and `marketingName`** are the site's "Merk" and "Brand" columns; the second is
  often the brand again or brand plus model.
- **Certificate numbers** can repeat, in both lists, when a revision ("/R/") was recorded
  as a second row with its own issue timestamp (one such pair among the 1,000 newest issued
  certificates on 2026-10-14; the two rows may differ in `isValid`). Both rows are output.

### Pricing

Pay per event:

| Event            | Charged for                                 |
| ---------------- | ------------------------------------------- |
| `product-record` | Each certificate row stored in the dataset. |

Apify's standard run-start event covers starting the actor. Rows are stored first and
charged after, so you never pay for data you did not receive. When your spending limit runs
out, the run stops cleanly and never stores an unpaid row.

### Data source and politeness

- **Source:** the public certificate pages of the SDPPI e-certification portal,
  `https://sertifikasi.postel.go.id/sertifikat/sertifikat-terbit` and
  `https://sertifikasi.postel.go.id/sertifikat/sertifikat-pencabutan`. Each page loads its
  rows from the portal's own query service; the actor sends the same two requests the pages
  send (a count and a page of rows), with the same headers, asking for 500 rows at a time
  instead of 10. No login, no captcha, no session. TLS certificates are always verified.
- **robots.txt:** the portal has none. The actor still
  - waits **at least 1 second** after each request ends before the next one starts (retries
    included; a constant, not an input),
  - uses **one connection**, one request at a time,
  - identifies itself honestly as `id-sdppi-actor/0.1 (+https://apify.com/a-g-d/id-sdppi)`,
  - asks only for the rows it needs: the 20 newest certificates take 2 requests.
- **Measured on 2026-10-14:** the 20 newest certificates in 2 requests and 2 s; 1,000
  certificates in 3 requests and 3 s (two 500-row pages, about 50 KB each on the wire,
  250 KB uncompressed); a keyword search (`Xiaomi`, 523 matches) 200 rows in 2 requests
  and 2 s; `manufacturerCountry: "VN"` 200 rows from 2,500 read in 6 requests and 7 s;
  `issuedSince: "2026-10-01"` 464 certificates in 3 requests and 3 s.
- **Resilience:** connection errors, timeouts, HTTP 5xx and 429, redirects, answers that
  are not JSON and query errors are retried with exponential backoff and jitter inside a
  run-wide budget (90 s of backoff). A refusal (the service's `forbidden` answer, HTTP
  401/403/404), a challenge page or a changed answer shape stops the run with a clear
  message rather than working around it.
- **Terms:** the portal publishes no terms of use. Its public manual and its service notice
  (Decree 26/2025 of the Director of Digital Infrastructure Services) say nothing about
  automated access or reuse; the manual's only legal text is "Hak Cipta © 2022 Direktorat
  Jenderal Sumber Daya dan Perangkat Pos dan Informatika" (copyright, Directorate General
  of Resources and Equipment for Post and Information Technology). The lists are published
  so the public can check certificates. Check the regulator's rules for your own use of
  the data.

### Data and privacy

The register publishes product and company data: certified devices, the companies that
applied for and manufacture them, and dates. The actor outputs only the fields listed
above.

- **Only the public list's fields are requested.** The portal's query service also carries,
  for its logged-in users, the applicant's tax number, phone, fax and e-mail, deed and
  business numbers, addresses, the contact person's name, phone and e-mail, device IMEIs
  and certificate files. The actor never asks for any of them, not even the site's customer
  identifier, and never opens a certificate's detail record.
- **Companies, as published.** Every applicant and manufacturer seen (the 500 newest issued
  certificates and all 219 revoked ones on 2026-10-14) is a company, and no value carried an
  e-mail address or phone number. Should the regulator ever list a sole trader as applicant,
  the actor outputs the name exactly as the public register does and adds no contact data.
  Indonesia's Personal Data Protection Law (UU 27/2022) applies to personal data you store:
  use the data for the purpose it is published for, checking devices and their approvals.

### Limitations

- **Only what the two public lists show.** There is no per-certificate detail (test
  reports, frequency bands, technical files) in the output, by design.
- **Country and date filters read the whole range they cover.** `manufacturerCountry`,
  `issuedBefore` and `expiringBefore` are checked per row, so a country filter over the
  whole issued list reads about 240 pages (about 6 minutes at 1 s spacing; raise the run
  timeout). Combine them with `issuedSince`, `brand`, `model` or `applicant` to narrow the
  read.
- **The site's matches are "contains".** `brand: "mi"` also matches "Xiaomi" and "Mijia".
- **A run is a snapshot.** Certificates issued while a long run pages through the list
  belong to the next run; a row seen twice is stored once.
- **Which rows each list holds is the regulator's choice.** The two lists together hold
  118,671 of the 121,511 certificates the service counts without a list filter; the rest
  appear on neither public page and are not available.

# Changelog

This Actor's version history is a separate document: https://apify.com/a-g-d/id-sdppi/changelog.md

# Actor input Schema

## `list` (type: `string`):

Which public list to read: the issued certificates (Sertifikat Terbit, about 118,000 certificates, newest first) or the revoked certificates (Sertifikat Pencabutan, about 220).

## `keyword` (type: `string`):

The site's own search: certificate number, applicant, device name, brand, model or marketing name contains this text, any case, e.g. "Xiaomi" or "router". Leave empty for all.

## `brand` (type: `string`):

The brand ("Merk") contains this text, any case, e.g. "xiaomi". Applied by the site. Leave empty for all.

## `model` (type: `string`):

The model designation contains this text, any case, e.g. "M2320". Applied by the site. Leave empty for all.

## `applicant` (type: `string`):

The applicant (certificate holder, "Nama Pemohon") contains this text, any case, e.g. "erajaya". Applied by the site. Leave empty for all.

## `manufacturerCountry` (type: `string`):

Two-letter ISO country code of the country of manufacture, e.g. CN, VN, ID. Checked on each row while paging newest first, so it reads the whole list it has to cover. Leave empty for all.

## `issuedSince` (type: `string`):

Only certificates issued on or after this date (YYYY-MM-DD, Indonesian calendar date). The list is newest first, so the run stops once it passes this date.

## `issuedBefore` (type: `string`):

Only certificates issued before this date (YYYY-MM-DD).

## `expiringBefore` (type: `string`):

Only certificates whose validity ends before this date (YYYY-MM-DD). Checked on each row while paging newest first.

## `maxItems` (type: `integer`):

Stop after storing this many certificates (1 to 50,000). The default 300 s run timeout covers about 50,000 rows without local filters; with a country or date filter the actor reads up to 500 rows a second.

## `proxyConfiguration` (type: `object`):

Optional. Use Apify Proxy if sertifikasi.postel.go.id is unreachable from Apify's network.

## Actor input object example

```json
{
  "list": "issued",
  "keyword": "",
  "brand": "",
  "model": "",
  "applicant": "",
  "manufacturerCountry": "",
  "issuedSince": "",
  "issuedBefore": "",
  "expiringBefore": "",
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}
```

# Actor output Schema

## `certificates` (type: `string`):

One item per certificate matching the input: certificate number, issue and expiry timestamps, validity flag, applicant, application ID, legal basis, manufacturer and its country, device name, brand, marketing name, model, last update, source page and fetch time. The dataset has one table view per list.

# 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 = {
    "list": "issued",
    "maxItems": 20,
    "proxyConfiguration": {
        "useApifyProxy": false
    }
};

// Run the Actor and wait for it to finish
const run = await client.actor("a-g-d/id-sdppi").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 = {
    "list": "issued",
    "maxItems": 20,
    "proxyConfiguration": { "useApifyProxy": False },
}

# Run the Actor and wait for it to finish
run = client.actor("a-g-d/id-sdppi").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 '{
  "list": "issued",
  "maxItems": 20,
  "proxyConfiguration": {
    "useApifyProxy": false
  }
}' |
apify call a-g-d/id-sdppi --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,a-g-d/id-sdppi"
        }
    }
}
```

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/T6FREQul2eJ9DoQQY/builds/69twwQkkWbjq4TcEJ/openapi.json
