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.

Authentication

All API requests require your API token. You can find your token on the Integrations page.

Your token is included in the URL path:

https://changeflow.com/api/v3/{YOUR_TOKEN}/sources

Keep your API token secure - anyone with your token can access your account data.

Base URL

All API endpoints use this base URL:

https://changeflow.com/api/v3/{YOUR_TOKEN}

Endpoints

List Sources

Retrieve all your monitored sources.

GET /api/v3/{token}/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": ["[email protected]"],
    "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/{token}/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": ["[email protected]"],
  "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",
      "thumbnail": "https://cdn.changeflow.com/screenshots/thumb123.png",
      "diff_image": "https://cdn.changeflow.com/diffs/diff123.png",
      "diff_url": "https://changeflow.com/tracks/abc123/versions/456",
      "url": "https://changeflow.com/tracks/abc123/versions/456",
      "track_id": "abc123",
      "version_id": 456,
      "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. The response format matches the webhook payload, making it easy to use the same code for both.

GET /api/v3/{token}/changes

Optional Parameters:

  • limit - Maximum number of results (default: 100)
  • tag - Filter by tag name
  • source_id - Filter by specific source ID
  • q or search - Search by source title or URL
  • format - Response format: json (default), csv, or rss

Response:

[
  {
    "type": "link",
    "title": "New Product Launch Announced",
    "description": "Competitor announces new enterprise product line with AI features",
    "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": {
      "clean": "# New Product Launch\n\nFull article content in markdown...",
      "rich": "# New Product Launch\n\nContent with LD+JSON metadata..."
    }
  },
  {
    "type": "change",
    "title": "Pricing Page Updated",
    "description": "Enterprise plan price increased from $99 to $149/month",
    "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"
  }
]

Note: The markdown field is only included for link type changes and contains:

  • clean - Clean markdown version of the linked page content
  • rich - Rich markdown including metadata like LD+JSON and meta descriptions

Create Source

Create a new monitored source.

POST /api/v3/{token}/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": ["[email protected]"]
}

Response:

{
  "status": "success",
  "id": "abc123"
}

Update Source

Update an existing source's settings.

PUT /api/v3/{token}/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/{token}/sources/{id}

Response:

{
  "status": "success",
  "id": "abc123"
}

Pause/Resume/Check Source

Control source monitoring status.

Pause a source:

PUT /api/v3/{token}/sources/{id}/pause

Resume a source:

PUT /api/v3/{token}/sources/{id}/resume

Trigger an immediate check:

PUT /api/v3/{token}/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 doesn't exist)

Code Examples

Python

import requests

TOKEN = "your_api_token"
BASE_URL = f"https://changeflow.com/api/v3/{TOKEN}"

# List all sources
response = requests.get(f"{BASE_URL}/sources")
sources = response.json()

# Create a new source
new_source = {
    "url": "https://example.com/pricing",
    "looking_for": "Track pricing changes",
    "frequency": "daily"
}
response = requests.post(f"{BASE_URL}/sources", json=new_source)
result = response.json()
print(f"Created source: {result['id']}")

# Get a specific source with recent changes
response = requests.get(f"{BASE_URL}/sources/abc123")
source = response.json()
print(f"Source: {source['title']}")
for change in source['recent_changes']:
    print(f"  - {change['title']}")

# Get recent changes
response = requests.get(f"{BASE_URL}/changes", params={"limit": 50})
changes = response.json()
for change in changes:
    print(f"{change['type']}: {change['title']}")

JavaScript (Node.js)

const TOKEN = 'your_api_token';
const BASE_URL = `https://changeflow.com/api/v3/${TOKEN}`;

// List all sources
const sources = await fetch(`${BASE_URL}/sources`).then(r => r.json());

// Create a new source
const newSource = {
  url: 'https://example.com/pricing',
  looking_for: 'Track pricing changes',
  frequency: 'daily'
};
const result = await fetch(`${BASE_URL}/sources`, {
  method: 'POST',
  headers: { 'Content-Type': 'application/json' },
  body: JSON.stringify(newSource)
}).then(r => r.json());
console.log(`Created source: ${result.id}`);

// Get a specific source with recent changes
const source = await fetch(`${BASE_URL}/sources/abc123`).then(r => r.json());
console.log(`Source: ${source.title}`);
source.recent_changes.forEach(change => {
  console.log(`  - ${change.title}`);
});

// Get recent changes
const changes = await fetch(`${BASE_URL}/changes?limit=50`).then(r => r.json());
changes.forEach(change => {
  console.log(`${change.type}: ${change.title}`);
});

cURL

TOKEN="your_api_token"

# List sources
curl "https://changeflow.com/api/v3/$TOKEN/sources"

# Get a specific source
curl "https://changeflow.com/api/v3/$TOKEN/sources/abc123"

# Create source
curl -X POST "https://changeflow.com/api/v3/$TOKEN/sources" \
  -H "Content-Type: application/json" \
  -d '{"url":"https://example.com/pricing","looking_for":"Track pricing changes","frequency":"daily"}'

# Get changes
curl "https://changeflow.com/api/v3/$TOKEN/changes?limit=50"

# Pause a source
curl -X PUT "https://changeflow.com/api/v3/$TOKEN/sources/abc123/pause"

Rate Limits

The API has generous rate limits for normal usage. If you're making many requests in a short period, consider adding a small delay between calls.

Plan Requirements

The API is available on Business plans and above. If you don't see your API token on the integrations page, you may need to upgrade your plan.

Getting Help

If you need assistance with the API: