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
  • q or search - Search sources by title or URL
  • filter - Filter by status (running, paused, error)
  • format - Response format: json (default) or csv

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) or change (page changes only)
  • q or search - 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, or rss

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. Includes markdown with the full page content in markdown format.
  • change - A page content change detected. The description field 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 includes markdown with the full page content.
  • type=change - Only page content changes. Each includes description with 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: