# E-Rate Form 470 Scraper: School & Library Bids (`civitab/e-rate-form-470`) Actor

New E-Rate FCC Form 470 bid notices from US schools, libraries and consortia seeking internet, Wi-Fi, network gear and managed broadband. One row per application with service requests, RFP links and dates. Filter by state, year, category and keyword, or monitor new forms. No personal contact data.

- **URL**: https://apify.com/civitab/e-rate-form-470.md
- **Developed by:** [Jason Padilla](https://apify.com/civitab) (community)
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $5.00 / 1,000 form 470 notices

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

## E-Rate Form 470 Scraper: School & Library Bids

This Actor collects new E-Rate FCC Form 470 bid notices, the forms US schools, libraries and consortia post when they want quotes for internet access, Wi-Fi, cabling, network equipment or managed broadband. Each notice is one clean record per application with the applicant, state, funding year, service requests, capacity ranges, the allowable contract date and links to the form PDF and RFP documents. It reads the public USAC open-data API politely, needs no login, strips personal contact details and charges $0.005 per notice.

*By **Civitab**, independent public-data tools. Apify Store ID: `civitab/e-rate-form-470`.*

### What you get

Every Form 470 is a public request for bids: under E-Rate rules the applicant must wait at least 28 days after posting before signing a contract, so a fresh Form 470 is a live sales lead for internet providers, network integrators, Wi-Fi and cabling contractors and E-Rate consultants. USAC publishes the forms as one row per service request; this Actor groups those rows into **one item per application** and gives you:

- applicant organisation, type (school district, school, library, library system, consortium), city, state, ZIP and Billed Entity Number
- funding year, status, form version (original or amended), certified, last-modified and allowable contract dates
- every service request: category, service type, function, quantity, unit, minimum and maximum capacity, manufacturer
- Category 1 and Category 2 narratives, state or local procurement rules, installment options
- links to the certified Form 470 PDF and every uploaded RFP document
- the E-Rate consulting firm on the form (firm name and registration number only)

**Personal data is removed.** Contact person, technical contact and authorized person fields, the applicant e-mail, phone and street address are never requested from the API. E-mail addresses and phone numbers inside free text are replaced with `[removed]`; open the form PDF for the official contact route.

### Input example

Open Category 2 (Wi-Fi, switches, cabling) forms from Colorado and Texas posted in the last 14 days:

```json
{
  "daysBack": 14,
  "states": ["CO", "TX"],
  "serviceCategories": ["Category 2"],
  "maxItems": 200
}
```

### Output example

One real item from a live run on 22 Oct 2026 (long texts shortened):

```json
{
  "applicationNumber": "270001016",
  "formNickname": "CONVERSE CO  2.470.27.C2",
  "fundingYear": 2027,
  "status": "Certified",
  "formVersion": "Original",
  "applicantType": "School District",
  "billedEntityNumber": "142528",
  "billedEntityName": "CONVERSE CO SCHOOL DISTRICT 2",
  "billedEntityFccRegistrationNumber": "0012049268",
  "city": "GLENROCK",
  "state": "WY",
  "zip": "82637",
  "websiteUrl": null,
  "numberOfEligibleEntities": 4,
  "consultingFirms": [
    {
      "name": "BTU Consultants",
      "registrationNumber": "16049611"
    }
  ],
  "certifiedDate": "2026-10-21T20:20:36",
  "lastModifiedDate": "2026-10-21T20:20:36",
  "allowableContractDate": "2026-11-18T00:00:00",
  "rfpUploadDate": "2026-10-21T20:10:38",
  "hasRfp": true,
  "rfpDocumentUrls": [
    "https://publicdata.usac.org/EPC/Prd/Form470/270001016/142528/22575398-Converse2%20FY27%20MIBS%20RFP.xlsx"
  ],
  "formPdfUrl": "https://publicdata.usac.org/EPC/Prd/Form470/270001016/142528/22791742-USAC_FCC_FORM_470_APPLICATION_270001016_CERTIFIED.pdf",
  "category1Description": null,
  "category2Description": "Please see attached  Converse2 FY27 MIBS RFP  for details and specifications",
  "installmentType": null,
  "installmentMinYears": null,
  "installmentMaxYears": null,
  "hasStateOrLocalRestrictions": true,
  "stateOrLocalRestrictions": "Responses must be received via email only to  [removed] . Responses must include detailed pricing and descriptions. SPAM and/or robotic responses will not be...",
  "statewideState": null,
  "allPublicSchoolDistricts": false,
  "allNonPublicSchools": false,
  "allLibraries": false,
  "serviceCategories": [
    "Category 2"
  ],
  "serviceTypes": [
    "Managed Internal Broadband Services"
  ],
  "serviceRequestCount": 1,
  "serviceRequests": [
    {
      "serviceRequestId": "1",
      "serviceCategory": "Category 2",
      "serviceType": "Managed Internal Broadband Services",
      "function": "Existing Equipment",
      "otherFunction": null,
      "entities": 4,
      "quantity": null,
      "unit": null,
      "minimumCapacity": null,
      "maximumCapacity": null,
      "installationInitial": false,
      "maintenanceTechnicalSupport": null,
      "manufacturer": null,
      "otherManufacturer": null,
      "hasRfpAttachment": true
    }
  ],
  "sourceUrl": "https://opendata.usac.org/d/jt8s-3q52",
  "source": "Universal Service Administrative Company (USAC), E-Rate FCC Form 470 Tool Data, dataset jt8s-3q52; modified: contact fields removed, normalized",
  "attribution": "Universal Service Administrative Company",
  "license": "Public Domain",
  "scrapedAt": "2026-10-23T03:12:09Z"
}
```

### Fields

| Field | Type | Meaning |
|---|---|---|
| applicationNumber | string | Form 470 application number |
| billedEntityName, applicantType, city, state, zip | string | Applicant organisation and location |
| fundingYear | integer | E-Rate funding year (2027 = July 2027 to June 2028) |
| status, formVersion | string | Certified or Canceled; Original or Current (amended) |
| certifiedDate, lastModifiedDate, allowableContractDate | string | USAC timestamps (no time zone) |
| serviceCategories, serviceTypes | array | Distinct categories and service types on the form |
| serviceRequests | array | One object per service request (type, function, quantity, capacity, manufacturer) |
| hasRfp, rfpDocumentUrls, formPdfUrl | boolean, array, string | RFP flag and document links |
| category1Description, category2Description, stateOrLocalRestrictions | string | Narratives, personal details removed |
| consultingFirms | array | Firm name and registration number |
| source, attribution, license, sourceUrl, scrapedAt | string | Provenance on every item |

The full typed list is in the dataset schema (Output tab).

### Pricing (pay per event)

- **$0.005 per notice** (one Form 470 application with all its service requests), so $5 per 1,000.
- **$0.02 new-match alert**, charged at most once per run, only when *Only new* is on and the run found at least one new or amended notice.
- The default run (last 7 days, 50 notices) costs about $0.25. A daily all-states monitor finds about 30 to 40 forms a day in October, so roughly $0.17 to $0.22 a day including the alert.
- Set *Max cost per run* in Console; the Actor stops cleanly when it is reached and you are only charged for items saved to your dataset.

### Schedule and alerts

Turn on **Only new or amended notices**, pick your states and categories, and schedule the Actor daily in Console. Each run returns only forms you have not received yet (an amended form counts as new), and the ALERT record in the key-value store says how many were found. Connect the run to e-mail, Slack or a webhook with Apify integrations. AI agents can call it through the Apify MCP server as `civitab/e-rate-form-470`.

### Input reference

| Input | Default | Notes |
|---|---|---|
| daysBack | 7 | Forms certified or modified in the last N days; 0 = no date limit |
| modifiedSince | empty | Exact start date; overrides daysBack |
| fundingYears | all | e.g. \["2027"] |
| states | all | 2-letter codes |
| applicantTypes | all | School District, School, Library, Library System, Consortium |
| serviceCategories | both | Category 1 or Category 2 |
| keywords | none | Any word in nickname, narratives, service types, functions, manufacturers |
| statuses | Certified | Add Canceled to see cancelled forms |
| onlyWithRfp | false | Only forms with an RFP |
| maxItems | 50 | One notice per application |
| onlyNew | false | Monitor mode with cross-run memory per filter set |
| requestDelaySecs | 1 | 1 to 10 seconds between API requests |

### Source and license (robots.txt / terms checked 22 Oct 2026)

- **Source:** USAC Open Data portal, dataset "E-Rate FCC Form 470 Tool Data" (ID jt8s-3q52), read through its public SODA JSON API. No login, no API key, no account.
- **License:** the dataset page lists the license as **Public Domain**, with attribution to the **Universal Service Administrative Company**. Every item carries that attribution and a note that it was modified (contact fields removed, normalized).
- **robots.txt** of the portal sets `Crawl-delay: 1` and disallows only the browse, login and OData paths; the JSON resource API this Actor uses is not disallowed. The Actor waits at least 1 second between requests and fetches 1,000 rows per request.
- **Terms:** the portal footer links the platform vendor's terms of service, which returned "page not found" on 22 Oct 2026, and USAC's own terms-of-use address also returned "not found"; no terms forbidding automated access to the public API were found. USAC's privacy policy is published on its site.
- Not affiliated with or endorsed by USAC or the FCC.

### FAQ and disclaimer

**Is this every Form 470?** It covers everything USAC publishes in the open dataset, which is updated as forms are certified. Very recent forms can appear with a short delay.

**Why are contact e-mails missing?** We do not output personal data. Use the form PDF or RFP documents linked in each item.

**What is the allowable contract date?** The earliest day the applicant may sign a contract. Bid deadlines are set by each applicant and are often earlier; check the RFP.

Data is provided as published by USAC, without warranty; always confirm details in the official form before bidding.

### Reliability and test results (22 Oct 2026)

- Default input (last 7 days, 50 notices): **50 notices in 4 s**, 1 request, 100% success.
- Last 30 days, no cap: **1,008 notices** from 7,406 rows in 11 s, 8 of 8 requests successful (100%).
- Monitor test under simulated pay per event: run 1 saved 18 Texas notices and charged 18 notices plus 1 alert ($0.11); run 2 found 0 new notices and charged nothing.
- 50 offline tests (parsing, grouping across pages, privacy stripping, filters, retries, charging, monitor memory).

# Changelog

This Actor's version history is a separate document: https://apify.com/civitab/e-rate-form-470/changelog.md

# Actor input Schema

## `daysBack` (type: `integer`):

Only forms certified or modified in the last N days. 0 = no date limit (use with funding years).

## `modifiedSince` (type: `string`):

Optional exact start date, e.g. 2026-10-01. Leave empty to use Days back.

## `fundingYears` (type: `array`):

E-Rate funding years, e.g. 2027. Empty = all years.

## `states` (type: `array`):

2-letter codes of applicant states, e.g. CO, TX. Empty = all states.

## `applicantTypes` (type: `array`):

Empty = all types.

## `serviceCategories` (type: `array`):

Category 1 = internet and data transmission; Category 2 = internal connections, Wi-Fi, managed broadband. Empty = both.

## `keywords` (type: `array`):

Match any word in the form nickname, narratives, service types, functions or manufacturers (case-insensitive). Empty = no keyword filter.

## `statuses` (type: `array`):

Certified = open for bids. Canceled forms are excluded by default. Empty list = both.

## `onlyWithRfp` (type: `boolean`):

Keep only forms where the applicant issued an RFP.

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

Stop after this many notices (one per application). Each notice is one billable event.

## `onlyNew` (type: `boolean`):

Skip notices delivered by earlier runs with the same filters. Use on a schedule; one alert event is charged when a run finds new notices.

## `requestDelaySecs` (type: `number`):

Politeness delay between API requests, 1-10 s (the portal robots.txt asks for 1 s).

## Actor input object example

```json
{
  "daysBack": 7,
  "modifiedSince": "",
  "fundingYears": [],
  "states": [],
  "applicantTypes": [],
  "serviceCategories": [],
  "keywords": [],
  "statuses": [
    "Certified"
  ],
  "onlyWithRfp": false,
  "maxItems": 50,
  "onlyNew": false,
  "requestDelaySecs": 1
}
```

# Actor output Schema

## `results` (type: `string`):

Dataset items. Field types are in the dataset schema.

## `runSummary` (type: `string`):

JSON: items pushed, request success rate, stop reason, charged events.

# 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 = {
    "daysBack": 7,
    "fundingYears": [],
    "statuses": [
        "Certified"
    ],
    "maxItems": 50
};

// Run the Actor and wait for it to finish
const run = await client.actor("civitab/e-rate-form-470").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 = {
    "daysBack": 7,
    "fundingYears": [],
    "statuses": ["Certified"],
    "maxItems": 50,
}

# Run the Actor and wait for it to finish
run = client.actor("civitab/e-rate-form-470").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 '{
  "daysBack": 7,
  "fundingYears": [],
  "statuses": [
    "Certified"
  ],
  "maxItems": 50
}' |
apify call civitab/e-rate-form-470 --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,civitab/e-rate-form-470"
        }
    }
}
```

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/ZQWGB0fEBchoIT6ar/builds/KRTSTHjYx1lD5tfqf/openapi.json
