Fetch school feeds from ParentSquare via their mobile JSON API. Outputs clean JSON with feed metadata, descriptions, and attachment info.
cp config.example.json config.json
# Edit config.json with your ParentSquare username, password, and school ID(s)Find your school ID by logging into ParentSquare and looking at the URL, or by running the scraper with a guess — it will return the school name in the output.
# Fetch feeds, output to stdout
python3 parentsquare.py
# Save to file
python3 parentsquare.py -o feeds.json:
# Fetch specific school
python3 parentsquare.py --school 16958
# Multiple schools
python3 parentsquare.py --school "16958,16959"
# Custom config location
python3 parentsquare.py --config /path/to/my-config.jsonJSON with this structure:
{
"scraped_at": "2026-05-21T12:00:00Z",
"schools": {
"16958": {
"name": "Radically Trans Elementary School",
"total_feeds": 42,
"feeds": [
{
"id": "123456",
"subject": "No gender and sexualities club today",
"created_at": "2026-05-21T08:30:00Z",
"author": "Mx. Teach (they/them)",
"feed_level": "class",
"description_text": "We have a field trip today to the local LGBT health organization, so no club meeting.",
"has_files": false,
"has_forms": false,
"has_volunteer_list": false,
"photos_count": 0,
"comments_count": 3
}
]
}
}
}| Field | Description |
|---|---|
id |
ParentSquare feed ID |
subject |
Post title |
created_at |
ISO timestamp |
author |
Teacher/staff name |
feed_level |
school, class, group, or district |
description_text |
Post body (HTML stripped) |
has_files |
Has file attachments |
has_forms |
Has signable forms |
has_volunteer_list |
Has volunteer signup |
has_wish_list |
Has wishlist |
has_payment_list |
Has payment request |
photos_count |
Number of photos |
comments_count |
Number of comments |
Uses ParentSquare's mobile API token endpoint. Tokens are cached for 1 hour in .ps-token next to the script.
- This uses the same API the ParentSquare mobile app uses
- No browser automation needed — just username/password
- Rate-limit friendly: paginated requests with reasonable defaults