Sources
A source is what a feed's items come from: a website, a listing page or a sitemap on a website, or a social account. The routes and the source shape are the same for event feeds and news feeds.
What you can do through the API
- Add a website.
{ "type": "site", "url": … }adds the whole site the URL is on, and starts a 14-day backfill: recent items from the site are added to the feed, then the site is monitored for new ones. A disabled feed (every new feed starts disabled) takes no items in until it is enabled (see What a new feed receives). - List, enable, disable and remove every source on your feeds, whatever its type.
Listing pages, sitemaps and social accounts (Instagram, TikTok, Twitter / X,
Facebook) are added by our team: contact support to add one. Sending another
type is refused with 422 SOURCE_TYPE_NOT_ALLOWED.
How a site is added
- The whole domain. The site is the URL's host, whatever the path:
https://www.carolinatheatre.org/eventsadds the whole site. The host is lowercased, the port is dropped and an international domain is stored as punycode. www.or not, one site.www.carolinatheatre.organdcarolinatheatre.orgare treated as the same site: if we already crawl one of them, it is reused, andidentity.domainshows the spelling we crawl. A site we do not crawl yet is stored under the host as you sent it,www.kept:https://www.carolinatheatre.org/eventsaddswww.carolinatheatre.org.- A URL of at most 2048 characters. A longer one is a
400INVALID_BODY. - A public domain. The host must be a public domain that resolves. A URL
that is not absolute http(s), an IP address, a private or internal name, or
a name without a dot is refused with
422VALIDATION_FAILED, each with its own message. A host we check by resolving it (one that resolves to a private address, does not resolve, or does not answer in time) gets one message,must name a publicly resolvable domain, whatever the reason. - Once per feed. A site the feed already has, under either spelling, is a
409ALREADY_EXISTS. - 30 adds a minute. Adding sites to your event and news feeds shares one
limit of 30 requests a minute per organization. A request counts once its
URL passes the checks above and its host is looked up, whether or not the
host resolves; a malformed body, a
typeother thansite, a URL refused before the lookup (not http(s), an IP address, a private or internal name, a name without a dot) and a request on a feed you cannot change do not. Over the limit the request is a429RATE_LIMITEDwith aRetry-Afterheader (seconds to wait). When the limit cannot be counted, the request is a503SERVICE_UNAVAILABLEwith aRetry-Afterheader. Listing, enabling, disabling and removing sources are not limited.
A site can be on several feeds, yours and other organizations'. Removing it from a feed removes it from that feed only.
Enabling, disabling and removing
- Disable (
PATCHwith{ "enabled": false }): the source stops contributing new items to this feed but stays on it. Enabling it again resumes monitoring; items published while it was disabled are not backfilled (unless the source has never brought in its past 14 days, see below). - Remove (
DELETE): the source leaves this feed.
We stop crawling a source when no enabled feed uses it.
A source is named by its feed-source id, as the list returns it. An id
that belongs to another feed is a 404.
What a new feed receives
Each source brings into the feed, once, the items it brought in during the past 14 days that pass the feed's filters, whether they were crawled for this feed or already for another:
- When you enable the feed, from each enabled source that has not brought them in yet. A new feed starts disabled, so its sources bring them in when you first enable it, and a source added while the feed was disabled brings them in when you enable it again.
- When you add a source to an enabled feed, right away.
- When you enable a source of an enabled feed that has not brought them in yet.
A source that has brought them in does not bring them in again: re-enabling the feed or the source does not add the items published while it was disabled. If bringing them in is interrupted (the feed or the source is disabled before it finishes), the next enable starts it again.
Who can see a feed's sources
The feed's owner can read and change its sources. An organization subscribed
to the feed can list them, and gets 403 PERMISSION_DENIED on a change.
Any other organization gets 404.
The source
{
"id": "9b2f6c1e-4d3a-4e8b-9c7d-2a1b0f3e5d64",
"type": "site",
"identity": {
"domain": "carolinatheatre.org"
},
"enabled": true,
"addedAt": "2026-10-28T14:05:00.000Z"
}
| Field | Description |
|---|---|
id | Stable feed-source identifier: the sourceId of the PATCH and DELETE routes |
type | site, siteIndexPage (a listing page), sitemap, instagram, tiktok, twitter or facebook |
identity | What is crawled, by type (below). null when the source's crawl record no longer exists |
enabled | Whether the source contributes new items to this feed |
addedAt | When the source was added to the feed (ISO 8601) |
type | identity |
|---|---|
site | domain: the site as we crawl it, e.g. carolinatheatre.org or www.carolinatheatre.org |
siteIndexPage, sitemap | domain of the site, and url of the page |
instagram, tiktok, twitter | handle, without @ |
facebook | facebookType (page, group or profile), id (Facebook's own id) and handle when it has one |
API reference
{type} is events or news.
| Route | Does |
|---|---|
GET /feeds/{type}/{id}/sources | Every source on the feed, newest first |
POST /feeds/{type}/{id}/sources | Add a site |
PATCH /feeds/{type}/{id}/sources/{sourceId} | Enable or disable a source |
DELETE /feeds/{type}/{id}/sources/{sourceId} | Remove a source from this feed |
Add a site
POST /feeds/{type}/{id}/sources
{
"type": "site",
"url": "https://www.carolinatheatre.org/events"
}
Response 200 OK, for a site we did not crawl yet (stored as sent):
{
"success": true,
"data": {
"id": "9b2f6c1e-4d3a-4e8b-9c7d-2a1b0f3e5d64",
"type": "site",
"identity": {
"domain": "www.carolinatheatre.org"
},
"enabled": true,
"addedAt": "2026-10-28T14:05:00.000Z"
}
}
List sources
GET /feeds/{type}/{id}/sources
Returns { "success": true, "data": [ … ] }, each entry a source as above.
Enable or disable a source
PATCH /feeds/{type}/{id}/sources/{sourceId}
{ "enabled": false }
Returns the source.
Remove a source
DELETE /feeds/{type}/{id}/sources/{sourceId}
Returns { "success": true }.
Errors
| Status | Code | When |
|---|---|---|
400 | INVALID_BODY | The body is malformed, or the URL is longer than 2048 characters |
403 | PERMISSION_DENIED | A change by an organization that subscribes to the feed but does not own it |
404 | NOT_FOUND | No such feed, or a sourceId that is not on this feed |
409 | ALREADY_EXISTS | The feed already has this site, with or without www. |
422 | SOURCE_TYPE_NOT_ALLOWED | A type other than site |
422 | VALIDATION_FAILED | The URL is not an absolute http(s) URL, or its host is not a public domain that resolves |
429 | RATE_LIMITED | More than 30 site adds in a minute by your organization. Retry after Retry-After |
503 | SERVICE_UNAVAILABLE | Adds cannot be counted against the limit right now. Retry after Retry-After |