Ncleg APIncleg.gov ↗
Retrieve North Carolina General Assembly streamed events by date via the ncleg.gov API. Get titles, stream links, UTC start times, and event status.
What is the Ncleg API?
The ncleg.gov API exposes 1 endpoint — get_schedule — that returns the North Carolina General Assembly's streaming calendar for any single calendar date, covering sessions, committee meetings, and press conferences. Each response includes up to 9 fields per event: event ID, title, date, wall-clock time, UTC start time, status, stream link, location, and chamber. Pagination is built in via offset and limit parameters, with has_more and total_available for cursor tracking.
curl -X GET 'https://api.parse.bot/scraper/4bf314a4-9f49-4298-9ff1-1f787e1c4975/get_schedule?date=20261007' \ -H 'X-API-Key: $PARSE_API_KEY'
Typed, relational, agent-ready
A generated client with real types, enums, and the links between objects — the structure a flat JSON response can't carry. Autocompletes in your editor and reads cleanly to coding agents.
- Fully typed · autocompletes
- Objects link to objects
- Typed errors & pagination
Typed Python client. Set up the SDK in your uv project, then pull this API’s typed client:
uv add parse-sdk uv run parse init uv run parse add --marketplace ncleg-gov-api
uv run parse add --marketplace pulls a pinned snapshot of this canonical API — it won’t change underneath you. To customize it, subscribe and swap to your own copy.
"""Walkthrough: NC General Assembly schedule — list today's events."""
from parse_apis.ncleg_gov_api import NCLeg, InputFormatInvalid
client = NCLeg()
# List today's legislative events (limit caps total items fetched).
for event in client.events.list(limit=10):
loc = event.location
print(f"{event.time} {event.title} — {loc.full_name} [{event.status}]")
# Fetch one upcoming event to inspect optional fields.
event = client.events.list(limit=1).first()
if event is not None:
print(f"\nFirst event detail:")
print(f" ID: {event.event_id}")
print(f" Category: {event.category}")
print(f" Institution:{event.institution}")
print(f" Starts: {event.start_time_utc}")
if event.stream_url:
print(f" Stream: {event.stream_url}")
# Request a specific date; handle bad-format errors.
try:
for event in client.events.list(date="20261026", limit=5):
print(f"{event.date} {event.time} {event.title}")
except InputFormatInvalid:
print("Invalid date format — use YYYYMMDD.")
print("\nexercised: events.list / InputFormatInvalid")
Returns the legislative calendar events for one America/New_York calendar date, one item per calendar row, sliced by offset and limit. The requested date is always echoed in data.date; a date not shown on the calendar yields an empty items list (the calendar carries today's already-ended events plus upcoming days; past days are not available). data.total is the number of items in this page, data.total_available the number of events on that date before paging, and has_more is true only when offset + total < total_available. Rows that have an event detail page cost one extra request each (up to 40 per call) and gain url, player_url (YouTube watch URL), thumbnail, and format; other rows carry only what the calendar row shows. status is completed for rows the site marks Ended, scheduled for future starts, and live for a streaming row whose start time has passed today. stream_url (live audio mount, mapped from the room) is only present on scheduled or live rows; description (bill lines joined by newlines), format, url, player_url, thumbnail, and stream_url are omitted when not applicable. event_id is the site's numeric event id when present, otherwise a composite of session code, institution, date, title slug and time.
| Param | Type | Description |
|---|---|---|
| date | string | Calendar date in America/New_York as YYYYMMDD. Omitted = today's date in America/New_York. |
| limit | integer | Maximum events in the page; values above 100 are clamped to 100. |
| offset | integer | Number of that date's events to skip before the returned page. |
{
"type": "object",
"fields": {
"date": "requested date, YYYYMMDD",
"items": "array of event objects: event_id, title, date (YYYY-MM-DD), time (wall-clock text), start_time_utc (ISO-8601 Z), status (scheduled|live|completed), institution (house|senate|joint|committee|legislature), type (always event), category (session|committee|press_conference), optional format (video|audio), url, description, player_url, stream_url, thumbnail, and location {name, type, fullName}",
"limit": "limit applied",
"total": "number of items in this page",
"offset": "offset applied",
"has_more": "true when more events remain after this page",
"total_available": "number of events on the requested date before paging"
},
"sample": {
"data": {
"date": "20261026",
"items": [
{
"url": "https://www.ncleg.gov/LegislativeCalendarEvent/134586",
"date": "2026-10-26",
"time": "12:00 PM",
"type": "event",
"title": "House: Session Convenes",
"format": "video",
"status": "scheduled",
"category": "session",
"event_id": "134586",
"location": {
"name": "House",
"type": "chamber",
"fullName": "House"
},
"thumbnail": "https://i.ytimg.com/vi/htXaovraR1Y/hqdefault.jpg",
"player_url": "https://www.youtube.com/watch?v=htXaovraR1Y",
"stream_url": "https://audio1.ncleg.gov/house",
"institution": "house",
"start_time_utc": "2026-10-26T16:00:00Z"
},
{
"date": "2026-10-26",
"time": "12:00 PM",
"type": "event",
"title": "Senate: Session Convenes",
"format": "audio",
"status": "scheduled",
"category": "session",
"event_id": "2025:senate:20261026:senate-session-convenes:1200",
"location": {
"name": "Senate",
"type": "chamber",
"fullName": "Senate"
},
"stream_url": "https://audio2.ncleg.gov/senate",
"institution": "senate",
"start_time_utc": "2026-10-26T16:00:00Z"
}
],
"limit": 2,
"total": 2,
"offset": 0,
"has_more": true,
"total_available": 3
},
"status": "success"
}
}About the Ncleg API
What get_schedule Returns
The get_schedule endpoint accepts a date parameter in YYYYMMDD format, interpreted in the America/New_York timezone. Omitting date defaults to today. The response echoes the requested date in data.date and includes an items array of event objects. Each item carries event_id, title, a formatted date (YYYY-MM-DD), a human-readable time string (wall-clock text as it appears on the calendar), and a machine-readable start_time_utc in ISO-8601 Z format suitable for timezone-safe comparisons.
Event Fields and Status
Each event object includes a status field that distinguishes between scheduled, live, and completed states. A stream_link field provides the URL for the associated video stream where available. location describes the physical chamber or room, and a chamber field (e.g., Senate, House) allows filtering by legislative body at the application layer. Requesting a date with no scheduled events returns an empty items array rather than an error — the date and pagination metadata are still present.
Pagination
Results are paged using limit (capped at 100) and offset. The response includes total (items in the current page), total_available (all events on that date before paging), offset (applied skip), and has_more (boolean indicating whether additional events follow). This makes it straightforward to walk through a date with a high volume of simultaneous committee hearings.
The Ncleg API is a managed, monitored endpoint for ncleg.gov — not a raw scraper you maintain. Every endpoint is automatically health-checked on a schedule, and when ncleg.gov changes and a check fails, the API is automatically queued for repair and re-verified. It is built to keep working as the site underneath it changes.
This isn't an official ncleg.gov API — it's an independent, maintained REST wrapper over public data. Where the source has no official API (or only a limited one), Parse gives you a stable contract over a source that never promised one, and keeps it current. Need a new endpoint or field? You can revise it yourself in plain English and the agent rebuilds it against the live site in minutes — contributing the change back to the shared API is free.
Will this API break when the source site changes?+
Is this an official API from the source site?+
Can I fix or extend this API myself if I need a new endpoint or field?+
What happens if I call an endpoint that has an issue?+
- Display a live dashboard of today's NC General Assembly sessions, including stream links and room locations.
- Alert subscribers when a specific committee's status changes from 'scheduled' to 'live' using the
statusfield. - Aggregate historical committee meeting data by querying past dates via the
dateparameter. - Filter events by
chamberto build separate Senate and House streaming schedules. - Index
start_time_utcvalues to power calendar feeds or iCal exports normalized to any timezone. - Monitor the
has_moreflag to paginate through high-volume legislative days with many simultaneous hearings. - Power a public-facing 'watch live' page that surfaces only events with an active
stream_link.
| Tier | Price | Credits/month | Rate limit |
|---|---|---|---|
| Free | $0/mo | 200 | 5 req/min |
| Hobby | $30/mo | 1,000 | 20 req/min |
| Developer | $100/mo | 5,000 | 100 req/min |
| Team | $300/mo | 20,000 | 300 req/min |
| Company | $1,000/mo | 100,000 | 500 req/min |
Each endpoint has a fixed posted price per successful call — most fall between 1 and 10 credits — shown on this API's page before you run it. Exceeding the rate limit returns a 429 response. Authenticate with the X-API-Key header.
Does ncleg.gov have an official developer API?+
What does the `status` field actually distinguish?+
status field on each event object reflects whether an event is scheduled (upcoming), currently live (streaming in progress), or completed. This allows client applications to filter or highlight events without polling the stream link directly.Does the API cover multiple days in a single request?+
get_schedule is scoped to a single America/New_York calendar date per request. To cover a range of dates, you issue one request per date and combine the items arrays. You can fork the API on Parse and revise it to add a date-range endpoint that aggregates multiple days in one call.Are archived video recordings or bill documents available through this API?+
What happens when I query a date that has no events scheduled?+
items array and total_available set to 0. The date field still echoes the requested date, so your application can distinguish an empty calendar day from an error.