The Changeflow API allows you to programmatically manage your sources and retrieve change data. You can list sources, create new ones, update settings, and fetch recent changes - all using simple HTTP requests.
The API is available on all plans. You can find your API token at changeflow.com/account/api.
Authentication
All API requests require your API token. You can find your token on the Integrations page.
Header Authentication (Recommended)
Pass your token in the Authorization header:
Authorization: Bearer YOUR_TOKEN
This is the standard method for scripts, chatbots, MCP servers, and any programmatic use.
URL Token Authentication
For RSS readers, feed URLs, and other tools that can't set headers, you can include the token in the URL path:
https://changeflow.com/api/v3/{YOUR_TOKEN}/sources
Both methods work on all endpoints. Header auth is preferred because it keeps your token out of server logs and browser history.
Base URL
https://changeflow.com/api/v3
Rate Limits
The API allows 100 requests per hour per account. If you exceed this limit, you'll receive a 429 Too Many Requests response with a Retry-After header.
Endpoints
List Sources
Retrieve all your monitored sources.
GET /api/v3/sources
Optional Parameters:
-
tag- Filter by tag name -
qorsearch- Search sources by title or URL -
filter- Filter by status (running, paused, error) -
format- Response format:json(default) orcsv
Response:
[
{
"id": "abc123",
"url": "https://competitor.com/pricing",
"title": "Competitor Pricing Page",
"looking_for": "Track pricing changes and new plan announcements",
"frequency": "daily",
"tags": ["competitors", "pricing"],
"notification_addresses": ["team@company.com"],
"last_checked": "2025-01-15T10:30:00Z",
"next_check": "2025-01-16T10:30:00Z",
"last_change": "2025-01-14T15:22:00Z",
"status": "running",
"created_at": "2024-12-01T09:00:00Z"
}
]
Get Source
Retrieve details for a single source, including its 25 most recent changes.
GET /api/v3/sources/{id}
Response:
{
"id": "abc123",
"url": "https://competitor.com/pricing",
"title": "Competitor Pricing Page",
"looking_for": "Track pricing changes and new plan announcements",
"frequency": "daily",
"tags": ["competitors", "pricing"],
"notification_addresses": ["team@company.com"],
"last_checked": "2025-01-15T10:30:00Z",
"next_check": "2025-01-16T10:30:00Z",
"last_change": "2025-01-14T15:22:00Z",
"status": "running",
"paused": false,
"created_at": "2024-12-01T09:00:00Z",
"change_type": "new_content",
"recent_changes": [
{
"type": "change",
"title": "Pricing Update",
"description": "Enterprise plan price increased from $99 to $149/month. The new pricing includes advanced analytics and AI-powered reporting.",
"track_id": "abc123",
"change_id": "v_456",
"source_name": "Competitor Pricing Page",
"source_url": "https://competitor.com/pricing",
"timestamp": "2025-01-14T15:22:00Z"
}
]
}
List Changes
Retrieve recent changes across all your sources.
GET /api/v3/changes
Optional Parameters:
-
limit- Maximum number of results (default: 100) -
tag- Filter by tag name -
source_id- Filter by specific source ID -
type- Filter by change type:link(new links only) orchange(page changes only) -
qorsearch- Search across change titles, descriptions, source names, URLs, and content -
since- ISO8601 timestamp to only return changes after this time (e.g.,2025-01-15T00:00:00Z) -
format- Response format:json(default),csv, orrss
Response:
[
{
"type": "link",
"title": "New Product Launch Announced",
"description": "Competitor announces new enterprise product line",
"thumbnail": "https://cdn.changeflow.com/images/thumb123.jpg",
"diff_image": "https://cdn.changeflow.com/diffs/diff123.png",
"diff_url": "https://changeflow.com/tracks/abc123/versions/789",
"url": "https://competitor.com/blog/new-product-launch",
"track_id": "abc123",
"version_id": 789,
"change_id": "l_456",
"source_name": "Competitor Blog",
"source_url": "https://competitor.com/blog",
"timestamp": "2025-01-15T14:30:00Z",
"markdown": "# New Product Launch\n\nFull article content in markdown...",
"changes": [
{
"description": "New blog post: Product Launch Announced",
"importance": 9,
"confidence": 9,
"change_type": "inserts",
"link": "https://competitor.com/blog/new-product-launch"
}
]
},
{
"type": "change",
"title": "Pricing Page Updated",
"description": "Enterprise plan price increased from $99 to $149/month. The new pricing includes advanced analytics and AI-powered reporting features.",
"thumbnail": "https://cdn.changeflow.com/screenshots/screen456.png",
"diff_image": "https://cdn.changeflow.com/diffs/diff456.png",
"diff_url": "https://changeflow.com/tracks/def456/versions/123",
"url": "https://changeflow.com/tracks/def456/versions/123",
"track_id": "def456",
"version_id": 123,
"change_id": "v_123",
"source_name": "Competitor Pricing",
"source_url": "https://competitor.com/pricing",
"timestamp": "2025-01-15T12:00:00Z",
"changes": [
{
"description": "Enterprise plan price changed from $99 to $149/month",
"importance": 9,
"confidence": 8,
"change_type": "edits"
},
{
"description": "New AI-powered reporting feature added",
"importance": 8,
"confidence": 9,
"change_type": "inserts"
}
]
}
]
Change types:
-
link- A new link discovered on a monitored page. Includesmarkdownwith the full page content in markdown format. -
change- A page content change detected. Thedescriptionfield contains an AI-generated markdown summary of what changed.
Both types include a changes array when available, containing the individual AI-filtered changes with description, importance (1-10), confidence (1-10), and change_type (inserts/deletes/edits). Only changes the AI deemed relevant are included.
Filtering Changes
The List Changes endpoint supports several filters that can be combined:
Keyword search (q or search) searches across:
- Change titles and descriptions
- Version summaries
- Source names and URLs
- Link titles, descriptions, and URLs
This means searching for "pricing" will find changes where "pricing" appears in the change summary, the source name, or the linked page description - not just the source URL.
Type filter (type) lets you get only one kind of change:
-
type=link- Only new links discovered on monitored pages. Each includesmarkdownwith the full page content. -
type=change- Only page content changes. Each includesdescriptionwith an AI-generated summary.
Since filter (since) returns only changes detected after the given timestamp. Use ISO8601 format (e.g., 2025-01-15T00:00:00Z). This is useful for polling - store the timestamp of your last request and only fetch new changes.
Combine filters for targeted queries:
GET /api/v3/changes?type=link&tag=competitors&q=pricing&since=2025-01-15T00:00:00Z&limit=20
Response Fields
Fields on all changes:
| Field | Type | Description |
|---|---|---|
type |
string |
"link" for new links, "change" for page changes |
title |
string | Short title of the change |
description |
string | AI-generated summary of what changed (markdown) |
thumbnail |
string | Thumbnail image URL |
diff_image |
string | Screenshot of the change |
diff_url |
string | URL to view the change in Changeflow |
url |
string | For links: the discovered URL. For changes: the diff viewer URL |
track_id |
string | Source ID (use with GET /sources/{id}) |
version_id |
integer | Internal version ID |
change_id |
string | Change ID (use with GET /changes/{id}). Format: v_123 or l_456
|
source_name |
string | Name of the monitored source |
source_url |
string | URL of the monitored source |
timestamp |
string | ISO8601 timestamp of when the change was detected |
changes |
array | AI-filtered changeset (when available). Each item has description, importance, confidence, and change_type
|
Additional fields on link changes:
| Field | Type | Description |
|---|---|---|
markdown |
string | Full page content of the linked URL in clean markdown format |
Fields in the changes array:
| Field | Type | Description |
|---|---|---|
description |
string | What this specific change is |
importance |
integer | 1-10 relevance score based on your source's monitoring prompt |
confidence |
integer | 1-10 confidence that this is a real, meaningful change |
change_type |
string |
"inserts" (new content), "deletes" (removed content), or "edits" (modified content) |
link |
string | For link-type changes: the URL of the discovered link |
Get Change
Retrieve a single change by its ID with full content.
GET /api/v3/changes/{change_id}
The change_id is returned in list responses (e.g., v_456 for version changes, l_789 for link changes).
Response (link change):
{
"type": "link",
"title": "New Product Launch Announced",
"description": "Competitor announces new enterprise product line",
"url": "https://competitor.com/blog/new-product-launch",
"track_id": "abc123",
"change_id": "l_456",
"source_name": "Competitor Blog",
"source_url": "https://competitor.com/blog",
"timestamp": "2025-01-15T14:30:00Z",
"markdown": "# New Product Launch\n\nFull article content in markdown...",
"changes": [
{
"description": "New blog post: Product Launch Announced",
"importance": 9,
"confidence": 9,
"change_type": "inserts",
"link": "https://competitor.com/blog/new-product-launch"
}
]
}
Response (version change):
{
"type": "change",
"title": "Pricing Page Updated",
"description": "Enterprise plan price increased from $99 to $149/month. The new pricing includes advanced analytics and AI-powered reporting features.",
"url": "https://changeflow.com/tracks/def456/versions/123",
"track_id": "def456",
"change_id": "v_123",
"source_name": "Competitor Pricing",
"source_url": "https://competitor.com/pricing",
"timestamp": "2025-01-15T12:00:00Z",
"changes": [
{
"description": "Enterprise plan price changed from $99 to $149/month",
"importance": 9,
"confidence": 8,
"change_type": "edits"
}
]
}
Create Source
Create a new monitored source.
POST /api/v3/sources
Content-Type: application/json
Required Fields:
-
url- The URL to monitor -
looking_for- What you want to track (the monitoring prompt) -
frequency- Check frequency (e.g., "hourly", "daily", "weekly")
Optional Fields:
-
title- Custom name for the source (auto-generated from page title if not provided) -
tags- Array of tag names or comma-separated string -
notification_addresses- Array of email addresses to notify
Request:
{
"url": "https://competitor.com/pricing",
"looking_for": "Track any pricing changes, new plans, or promotional offers",
"frequency": "daily",
"title": "Competitor Pricing",
"tags": ["competitors", "pricing"],
"notification_addresses": ["alerts@company.com"]
}
Response:
{
"status": "success",
"id": "abc123"
}
Update Source
Update an existing source's settings.
PUT /api/v3/sources/{id}
Content-Type: application/json
Fields (all optional):
-
title- Update the source name -
looking_for- Update the monitoring prompt -
frequency- Update check frequency -
tags- Replace all tags -
notification_addresses- Replace all notification addresses
Request:
{
"frequency": "hourly",
"looking_for": "Track pricing changes, especially enterprise tier",
"tags": ["competitors", "pricing", "high-priority"]
}
Response:
{
"status": "success",
"id": "abc123"
}
Delete Source
Permanently delete a source and all its history.
DELETE /api/v3/sources/{id}
Response:
{
"status": "success",
"id": "abc123"
}
Pause/Resume/Check Source
Control source monitoring status.
Pause a source:
PUT /api/v3/sources/{id}/pause
Resume a source:
PUT /api/v3/sources/{id}/resume
Trigger an immediate check:
PUT /api/v3/sources/{id}/check
Response:
{
"status": "success",
"id": "abc123"
}
Frequency Values
When creating or updating sources, use these frequency values:
| Value | Description |
|---|---|
5_minutes |
Every 5 minutes |
10_minutes |
Every 10 minutes |
30_minutes |
Every 30 minutes |
hourly |
Every hour |
2_hours |
Every 2 hours |
4_hours |
Every 4 hours |
8_hours |
Every 8 hours |
daily |
Once per day |
weekly |
Once per week |
monthly |
Once per month |
Error Responses
When an error occurs, the API returns a JSON response with an error message:
{
"status": "error",
"error": "url is required"
}
Common HTTP status codes:
-
200- Success -
400- Bad request (missing or invalid parameters) -
403- Forbidden (invalid API token) -
404- Not found (source or change doesn't exist) -
429- Too many requests (rate limit exceeded)
Code Examples
Python
import requests
TOKEN = "your_api_token"
BASE = "https://changeflow.com/api/v3"
HEADERS = {"Authorization": f"Bearer {TOKEN}"}
# List all sources
sources = requests.get(f"{BASE}/sources", headers=HEADERS).json()
# Create a new source
new_source = {
"url": "https://example.com/pricing",
"looking_for": "Track pricing changes",
"frequency": "daily"
}
result = requests.post(f"{BASE}/sources", json=new_source, headers=HEADERS).json()
print(f"Created source: {result['id']}")
# Get recent changes (links only, with keyword search)
changes = requests.get(f"{BASE}/changes", params={
"type": "link",
"q": "pricing",
"limit": 50
}, headers=HEADERS).json()
for change in changes:
print(f"{change['title']}")
if change.get('markdown'):
print(f" Content: {change['markdown'][:200]}...")
# Get changes since last check (for polling)
changes = requests.get(f"{BASE}/changes", params={
"since": "2025-01-15T00:00:00Z"
}, headers=HEADERS).json()
# Get a single change with full content
change = requests.get(f"{BASE}/changes/l_456", headers=HEADERS).json()
print(change['markdown']) # Full page content in markdown
JavaScript (Node.js)
const TOKEN = 'your_api_token';
const BASE = 'https://changeflow.com/api/v3';
const headers = { 'Authorization': `Bearer ${TOKEN}` };
// List all sources
const sources = await fetch(`${BASE}/sources`, { headers }).then(r => r.json());
// Get only new links (great for AI processing)
const links = await fetch(`${BASE}/changes?type=link&limit=20`, { headers })
.then(r => r.json());
links.forEach(link => {
console.log(`${link.title}: ${link.url}`);
console.log(`Markdown: ${link.markdown?.substring(0, 200)}...`);
});
// Poll for new changes since last check
const since = new Date(Date.now() - 3600000).toISOString(); // last hour
const newChanges = await fetch(`${BASE}/changes?since=${since}`, { headers })
.then(r => r.json());
// Get full details for a specific change
const change = await fetch(`${BASE}/changes/v_123`, { headers }).then(r => r.json());
console.log(change.description); // AI summary of what changed (markdown)
cURL
TOKEN="your_api_token"
# List sources
curl -H "Authorization: Bearer $TOKEN" \
"https://changeflow.com/api/v3/sources"
# Get only link changes with keyword search
curl -H "Authorization: Bearer $TOKEN" \
"https://changeflow.com/api/v3/changes?type=link&q=pricing"
# Get changes since a timestamp
curl -H "Authorization: Bearer $TOKEN" \
"https://changeflow.com/api/v3/changes?since=2025-01-15T00:00:00Z"
# Get a single change
curl -H "Authorization: Bearer $TOKEN" \
"https://changeflow.com/api/v3/changes/l_456"
# Get changes as RSS (URL token - for feed readers)
curl "https://changeflow.com/api/v3/$TOKEN/changes?format=rss"
Getting Help
If you need assistance with the API:
- Email: hello@changeflow.com
- Webhook integration: See Webhooks documentation for push notifications
- Feeds: See Feeds documentation for RSS, JSON, and CSV feeds