Windsor.ai Connectors API Documentation

Overview

Windsor.ai Connectors provide a unified API to access data from over 300 marketing, analytics, and business platforms. This documentation will guide you through the process of using our API to retrieve data from various sources.

Getting started

Authentication

All API requests require an API key for authentication. You can obtain your API key from your Windsor.ai account.

Include your API key in all requests using the api_key parameter:

https://connectors.windsor.ai/{connector}?api_key=your_api_key_here&fields=date,spend

Alternatively, you can pass your API key in a request header instead of the query string. This is useful when your client injects secrets into request headers rather than the URL (for example, agent platforms such as Anthropic’s Claude). Send it either as an X-Api-Key header:

X-Api-Key: your_api_key_here

or as a bearer token in the Authorization header:

Authorization: Bearer your_api_key_here

All three methods are equivalent and return the same data. If you supply the key both as a query parameter and as a header, the query parameter takes precedence.

Base URL

The base URL for all API requests is:

https://connectors.windsor.ai

Making API requests

Basic request structure

A basic API request follows this format:

https://connectors.windsor.ai/{connector}?fields={field1,field2,...}&api_key={your_api_key}

Where:

  • {connector} is the name of the data source (e.g., facebook, googleanalytics4, linkedin)
  • {field1,field2,...} is a comma-separated list of fields you want to retrieve
  • {your_api_key} is your Windsor.ai API key

Required parameters

Every API request must include these parameters:

Parameter Description
api_key Your Windsor.ai API key
fields Comma-separated list of fields to retrieve

Optional parameters

You can customize your data request with these optional parameters:

Parameter Description Example
date_preset Predefined date range last_7d, last_30d, last_90d, last_year
date_from Start date (YYYY-MM-DD) 2023-01-01
date_to End date (YYYY-MM-DD) 2023-01-31
_max_rows Maximum number of records to return 100
filter Filter expression [[“campaign”,”eq”,”search_competitors_tier1″]]

Public (sub)hourly refreshes via API

You can control how often recent data is refreshed from the upstream platform by using two parameters:refresh_since and refresh_interval.

This behaves the same way as our scheduled destination tasks (in databases and warehouse destinations), but is exposed publicly via the Connectors API.

All requests using these parameters remain subject to the global API rate limits.

How these parameters work:

1) refresh_since

  • Default: 3d (currently, it supports only the last 3 days).
  • Defines the recent time window that will be retrieved again from the upstream API.
  • Data within this period is re-fetched according to refresh_interval.
  • Data older than this period is considered stable and will be served from the cache if available.
  • The global cache refresh interval doesn’t apply to this stable data.

2) refresh_interval

  • Default: 6h.
  • Defines how often data in the refresh_since window should be refreshed from the upstream API.
  • The system will request new data from the source at most once every refresh_interval.
  • This setting doesn’t affect the stable cache outside the refresh_since window.

Notes: 

The minimum allowed refresh_interval depends on your plan:

  • STANDARD and PLUS plans can use refresh_interval=1h or more (e.g. 1h, 2h, 6h, …).;
  • PROFESSIONAL and ENTERPRISE tiers can use refresh_interval=15min or more (e.g. 15min, 30min, 1h, …).

Example:

To refresh the last 3 days of Google Ads data at least once per hour:

https://connectors.windsor.ai/google_ads?api_key=API_KEY&fields=date,campaign,spend&refresh_since=3d&refresh_interval=1h

 

Code examples

Python

import requests

API_KEY = "your_api_key_here"
connector = "facebook"
fields = "date,campaign,spend,impressions,clicks"

url = f"https://connectors.windsor.ai/{connector}?api_key={API_KEY}&fields={fields}"

response = requests.get(url)
print(response.json())

Javascript

const API_KEY = "your_api_key_here";
const connector = "facebook";
const fields = "date,campaign,spend,impressions,clicks";

const url = `https://connectors.windsor.ai/${connector}?api_key=${API_KEY}&fields=${fields}`;

fetch(url)
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error("API error:", err));

Write actions

Some connectors expose write actions: operations that change something on the source platform (for example create or pause a campaign, set a budget, or boost a post) rather than only reading data. The same endpoint is used to discover the available actions and to execute them. It powers the write capabilities exposed to Claude and other LLMs through the Windsor.ai MCP, and can be called directly from your own software.

Write actions must be enabled for your team before they can be executed. Enable them under Team management. Available actions differ per connector, so always call the list endpoint (GET) first rather than assuming an action exists.

List actions

GET https://connectors.windsor.ai/{connector}/actions

Returns the write operations the connector supports, each with a JSONSchema describing its parameters. Authenticate with api_key or access_token as a query parameter.

Example request:

curl "https://connectors.windsor.ai/google_ads/actions?api_key=YOUR_API_KEY"

Example response:

[
  {
    "id": "create_campaign",
    "name": "Create campaign",
    "description": "Create a new campaign (created paused).",
    "schema": {
      "type": "object",
      "properties": {
        "name": { "type": "string" },
        "budget_amount_micros": { "type": "integer" },
        "channel_type": { "type": "string" },
        "bidding_strategy": { "type": "string" }
      },
      "required": ["name", "budget_amount_micros"]
    }
  }
]

Execute an action

POST https://connectors.windsor.ai/{connector}/actions

Runs one action against one connected account. Requires write actions to be enabled for the team. Send a JSON body with these fields:

Field Required Description
account Yes The connected account id to run the action against.
action Yes The action id from the list endpoint (for example create_campaign).
params No Object of action parameters, matching the action JSONSchema.

Example request:

curl -X POST "https://connectors.windsor.ai/google_ads/actions?api_key=YOUR_API_KEY" -H "Content-Type: application/json" -d '{"account":"1234567890","action":"create_campaign","params":{"name":"Summer Sale","budget_amount_micros":50000000,"channel_type":"SEARCH","bidding_strategy":"manual_cpc"}}'

Example success response:

{ "result": "Campaign 'Summer Sale' created successfully with status PAUSED." }

Error responses: 400 for a missing field or invalid parameters, 403 if write actions are not enabled for the team, 404 for an unknown connector, and 500 for an unexpected error.

Date filtering

You can specify date ranges in two ways:

  1. Using date_preset:

    https://connectors.windsor.ai/facebook?fields=date,spend&date_preset=last_30d
  2. Using date_from and date_to:

    https://connectors.windsor.ai/facebook?fields=date,spend&date_from=2023-01-01&date_to=2023-01-31&api_key={your_api_key}

⚠️  Note: If date_to is not set, the query defaults to today and retrieves the most recent available data up to the current date. 

Simple presets

  • last_7d (last 7 days)
  • last_30d (last 30 days)
  • last_90d (last 90 days)
  • last_year (previous calendar year)

General format
You can also use dynamic presets in the following formats:

  • last_Xd last X days
  • last_XdT last X days including today
  • last_Xw last X weeks
  • last_Xm last X months
  • last_Xy last X years

Year based

  • last_year previous calendar year
  • last_yearT previous calendar year including today
  • last_2years last 2 years
  • last_2yearsT last 2 years including today

Current period

  • this_month this month
  • this_monthT this month including today
  • this_year this year
  • this_yearT this year including today

Examples

  • last_7d
  • last_30dT
  • last_3m

Data filtering

Filters use a JSON array format for readability and grouping.

  • Each condition is a list: [field, operator, value]
  • Combine conditions with "and" / "or"
  • Nest lists to group conditions

Supported operators

Operator Description Example
eq Equals [["campaign", "eq", "Summer Sale"]]
neq Not equals [["campaign", "neq", "Winter Sale"]]
gt Greater than [["spend", "gt", 100]]
gte Greater or equal [["spend", "gte", 100]]
lt Less than [["spend", "lt", 100]]
lte Less or equal [["spend", "lte", 100]]
contains Contains substring [["campaign", "contains", "Sale"]]
ncontains Does not contain substring [["campaign", "ncontains", "Test"]]
null Field is null [["clicks", "null", null]]
notnull Field is not null [["clicks", "notnull", null]]

Examples

⚠️ Note: For actual API requests, URL-encode the filter parameter. The examples below are shown in plain JSON for readability.

  • Single filter:

https://connectors.windsor.ai/facebook?fields=date,campaign,spend&filter=[["campaign","eq","Summer Sale"]]&api_key={your_api_key}
  • Check for null values:
https://connectors.windsor.ai/facebook?fields=date,campaign,clicks&filter=[["clicks","null",null]]&api_key={your_api_key}
  • Multiple conditions (AND):

https://connectors.windsor.ai/facebook?fields=date,spend&filter=[["spend","gt",100],"and",["campaign","contains","Sale"]]&api_key={your_api_key}
  • Nested groups (AND + OR):

https://connectors.windsor.ai/facebook?fields=date,campaign,spend&filter=[[["campaign","eq","foobar"],"or",["spend","eq",10]],"and",["campaign","eq","abc (us)"]]&api_key={your_api_key}

Code examples

Python

import requests
import json

api_key = "your_api_key_here"
connector = "facebook"
fields = "date,campaign,spend"

# Use json.dumps to convert the filter array to JSON string
filter_query = json.dumps([["spend","gt",100],"and",["campaign","contains","Sale"]])

url = f"https://connectors.windsor.ai/{connector}?api_key={api_key}&fields={fields}&filter={filter_query}"
response = requests.get(url)
print(response.json())

Javascript

const apiKey = "your_api_key_here";
const connector = "facebook";
const fields = "date,campaign,spend";

// Convert the filter array to JSON string
const filterQuery = JSON.stringify([["spend","gt",100],"and",["campaign","contains","Sale"]]);

const url = `https://connectors.windsor.ai/${connector}?api_key=${apiKey}&fields=${fields}&filter=${filterQuery}`;

fetch(url)
.then(res => res.json())
.then(data => console.log(data))
.catch(err => console.error("API error:", err));

Discovering available connectors and fields

Listing all connectors

You can get a list of all available connectors by making a request to:

https://connectors.windsor.ai/list_connectors

This endpoint returns a JSON array of all connectors that are available through the Windsor.ai API.

Retrieving available fields

To see what fields are available for a specific connector, use:

https://connectors.windsor.ai/{connector}/fields

For example, to get all available fields for Facebook:

https://connectors.windsor.ai/facebook/fields

When authenticated with your API key, this endpoint will also return any custom fields that have been configured for your account:

https://connectors.windsor.ai/facebook/fields?api_key={your_api_key}

The response includes detailed information about each field, including:

  • Field ID (used in API requests)
  • Field name (human-readable name)
  • Field type (TEXT, NUMERIC, DATE, etc.)
  • Field description

This information is essential for constructing effective API queries and understanding the data structure of each connector.

Connector options

Some connectors support additional configuration options.

These options allow you to customize how data is pulled — such as selecting accounts, toggling breakdowns, choosing report types, or enabling advanced filtering.

This endpoint returns all available options for a specific connector.

Get options for a specific connector

Endpoint

https://connectors.windsor.ai/{connector}/options

Replace {connector} with the connector ID (e.g., facebook, hubspot, salesforce).

Example (Facebook Ads)

Request:

https://connectors.windsor.ai/facebook/options

Example response (simplified):

{ "fields": [ { "key": "account_id", "label": "Ad Account", "type": "dropdown", "required": true, "values": [ { "id": "1234567890", "name": "ACME Ads Account" }, { "id": "9876543210", "name": "Europe Ads Account" } ] }, { "key": "breakdowns", "label": "Breakdowns", "type": "multi_select", "required": false, "values": [ "age", "gender", "country", "placement" ] }, { "key": "level", "label": "Reporting Level", "type": "select", "required": false, "values": [ "ad", "adset", "campaign", "account" ] } ] }

Typical use cases:

  • Build a UX for selecting Facebook Ad Accounts or Google Ads Customers
  • Display available report types or breakdown options
  • Validate user input when generating an authorization or sync configuration
  • Dynamically load options for any connector during onboarding

Supported connectors

Windsor.ai supports over 300 connectors, including:

  • Social Media: Facebook, Instagram, LinkedIn, Twitter, TikTok, Snapchat, Pinterest
  • Search & Display: Google Ads, Microsoft Bing, Google Search Ads, DV360, CM360
  • Analytics: Google Analytics 4, Adobe Analytics, Mixpanel, Amplitude
  • CRM & Marketing: Salesforce, HubSpot, Marketo, Mailchimp
  • E-commerce: Shopify, WooCommerce, Amazon, Stripe
  • And many more…

For a complete list of connectors and their specific fields, please refer to our Connectors Directory.

Field types

Fields returned by the API can have the following types:

Type Description Example
TEXT Text values Campaign names, ad titles
NUMERIC Numeric values Spend, impressions, clicks
TIMESTAMP Date and time values Date field
DATE Date values Date field
BOOLEAN Boolean values True/false flags
OBJECT Complex objects JSON structures

Response format

API responses are sent in JSON format:

{
  "data": [
    {
      "date": "2023-01-01",
      "spend": 125.45,
      "impressions": 10234,
      "clicks": 342
    },
    {
      "date": "2023-01-02",
      "spend": 134.67,
      "impressions": 11456,
      "clicks": 389
    }
  ]
}

Error handling

When an error occurs, the API will return an appropriate HTTP status code and a JSON response with error details:

{
  "error": {
    "code": "authentication_error",
    "message": "Invalid API key provided"
  }
}

Common error codes:

HTTP Status Error Code Description
400 invalid_request The request is malformed or missing required parameters
401 authentication_error Invalid API key or authentication credentials
403 permission_denied The API key doesn’t have permission to access the requested resource
404 not_found The requested connector or resource doesn’t exist
429 rate_limit_exceeded Too many requests in a given amount of time
500 server_error An unexpected server error occurred

Rate limits

API requests are subject to rate limits to ensure fair usage. The current rate limits are:

  • 600 requests per minute
  • 10,000 requests per day

If you exceed these limits, you’ll receive a 429 status code. The response will include headers indicating your remaining quota and when it will reset.

Renderers

The _renderer parameter specifies the format of the data returned by the Windsor.ai API. Available options include:

  • JSON: returns data in JSON format, ideal for web applications and integrations.
    https://connectors.windsor.ai/googleanalytics4?api_key=your_api_key&fields=date,spend&_renderer=json
  • CSV: returns data in CSV format, suitable for spreadsheets and data analysis.
    https://connectors.windsor.ai/googleanalytics4?api_key=your_api_key&fields=date,spend&_renderer=csv
  • Google Sheets: directly imports data into Google Sheets.
    https://connectors.windsor.ai/googleanalytics4?api_key=your_api_key&fields=date,spend&_renderer=googlesheets

Default: If no _renderer is specified, the API returns JSON format by default.

Windsor.ai provides an endpoint to generate a co-user authorization link. This allows your clients or teammates to connect their data sources without sharing credentials.

You can restrict the link to a single connector or allow any source.

Use this endpoint if you want the user to authorize only one specific data source.

https://onboard.windsor.ai/api/team/generate-co-user-url/?allowed_sources={source}&api_key={API_KEY}

Example (LinkedIn Ads only):

https://onboard.windsor.ai/api/team/generate-co-user-url/?allowed_sources=linkedin&api_key=YOUR_API_KEY

This link allows the user to connect only the LinkedIn data source.

Use this endpoint if you want the user to connect any data source supported by Windsor.ai:

https://onboard.windsor.ai/api/team/generate-co-user-url?api_key={API_KEY}

Example:

https://onboard.windsor.ai/api/team/generate-co-user-url?api_key=YOUR_API_KEY

This link lets the user choose and authorize any available connector.

Co-user linked accounts

These endpoints let you review and manage the accounts that your clients or teammates connected to your team through a co-user authorization link. Use GET to list the linked accounts, and DELETE to unlink one of them.

Endpoint URL:

GET    https://onboard.windsor.ai/api/team/co-user-linked-accounts/
DELETE https://onboard.windsor.ai/api/team/co-user-linked-accounts/

Both methods are available to the team owner only. A co-user who signed in through an authorization link cannot list or unlink accounts, and receives 403 Permission denied.

Authentication

You can authenticate your request in two ways:

1. API Key (Recommended for programmatic access): Append your API key to the request using the api_key query parameter.

2. Browser session: The endpoint can be accessed without an API key if the user is actively logged into https://onboard.windsor.ai in the same browser session.

Query parameters

Parameter Type Required Description
api_key string Yes* Your Windsor.ai API key (Not required if making a request from an authenticated browser session).
ds_id string No Filter the results by a specific data source ID  mysql, facebook_ads, etc.).
access_token string No Filter the results by a specific access token.

Important notes on the response

access_token vs co_user_member_name: The access_token value is only exposed for newly created authentication links. For existing/legacy auth links, the access_token will not be visible, and the co_user_member_name field will be shown instead.

Example requests

1. Basic request (All linked accounts)

HTTP

GET https://onboard.windsor.ai/api/team/co-user-linked-accounts/?api_key=YOUR_API_KEY

2. Filter by data source (ds_id)

To retrieve only linked accounts for a specific data source, such as MySQL:

HTTP

GET https://onboard.windsor.ai/api/team/co-user-linked-accounts/?api_key=YOUR_API_KEY&ds_id=mysql

3. Filter by access token (access_token)

To retrieve details for a specific access token:

HTTP

GET https://onboard.windsor.ai/api/team/co-user-linked-accounts/?api_key=YOUR_API_KEY&access_token=YOUR_ACCESS_TOKEN

Removes an account that was connected through a co-user authorization link from your team. The account is identified by the same values the GET response returns, so the usual flow is: list the linked accounts, pick the one you want to remove, then send a DELETE with its data source and account ID.

Query parameters:

Parameter Type Required Description
api_key string Yes* Your Windsor.ai API key (not required if making a request from an authenticated browser session).
ds_id string Yes Data source of the account to unlink (facebook_ads, mysql, etc.). This is the value returned as datasource in the GET response.
account_id string Yes The account to unlink, as returned in account_id by the GET response. Account IDs are unique per team and data source.
access_token string No Restrict the lookup to the accounts connected through this one authorization link. If the account was not connected through that link, the request returns 404. Legacy links without an access_token cannot be targeted this way, so omit the parameter for those.

Example requests:

1. Unlink an account

curl -X DELETE "https://onboard.windsor.ai/api/team/co-user-linked-accounts/?api_key=YOUR_API_KEY&ds_id=facebook_ads&account_id=act_123456789"

2. Unlink an account connected through a specific authorization link

curl -X DELETE "https://onboard.windsor.ai/api/team/co-user-linked-accounts/?api_key=YOUR_API_KEY&ds_id=facebook_ads&account_id=act_123456789&access_token=YOUR_ACCESS_TOKEN"

Successful response:

{
  "result": "facebook_ads account 'act_123456789' unlinked"
}

What happens when an account is unlinked

  • The account is removed from your team, stops appearing in the GET response, and its data is no longer served in connector responses.
  • For data sources where you pick accounts from a list after authorizing (most OAuth connectors), the account is deselected rather than erased. The authorization stays in place, so you can select the account again in the Windsor.ai app without asking for a new authorization link.
  • For all other data sources the stored account record is deleted, and reconnecting it requires a new authorization.
  • The authorization link itself is not revoked, and the other accounts connected through the same link stay connected. To remove several accounts, send one request per account.
  • The connection in the co-user’s own Windsor.ai team is not affected.

Response codes:

Code Meaning
200 The account was unlinked.
400 ds_id or account_id is missing, or the data source rejected the removal. The reason is in the error field.
403 The API key does not belong to the team owner.
404 No linked account matches the given ds_id and account_id, for example because it was already unlinked, or because it does not belong to the access_token you scoped the request to.

Example error response:

{
  "error": "Linked account not found"
}

Connector connect info

This endpoint describes how a data source can be connected to your Windsor.ai account: whether it authorizes via OAuth or manual credentials, a ready-to-use connect URL, and the credential fields required for manual connectors. Use it to build connection flows into your own tools, apps or AI assistants.

Get connect info for a data source

Endpoint:

https://onboard.windsor.ai/api/mcp/connectors/{connector}/connect-info?api_key={your_api_key}

Replace {connector} with the connector ID (e.g., facebook, google_ads, klaviyo). Same IDs as in the data API.

Parameter Type Required Description
connector string Yes The data source ID, passed in the URL path.
api_key string Yes* Your Windsor.ai API key (not required if making a request from an authenticated browser session).

Response fields

Field Type Description
connector string The connector ID you requested.
auth_type string oauth for connectors authorized via the provider’s consent screen; manual for connectors that require credentials entered by the user (e.g. an API key from the platform).
connect_url string A temporary sign-in link that opens the right connection screen: the provider’s authorization flow (OAuth) or the connector’s setup form (manual).
fields array For manual connectors, the credential fields required. Empty for OAuth connectors.

Each entry in fields has:

Field Type Description
name string Field identifier, e.g. account_name, api_key.
type string string, integer or boolean.
required boolean Whether the field must be provided.
sensitive boolean true for secrets (passwords, tokens, API keys).

Example responses

OAuth connector:

{ "connector": "facebook", "auth_type": "oauth", "connect_url": "https://onboard.windsor.ai/token-login?access_token={temporary_token}&next=/facebook/authorize", "fields": [] }

Manual connector:

{ "connector": "klaviyo", "auth_type": "manual", "connect_url": "https://onboard.windsor.ai/token-login?access_token={temporary_token}&next=/app/klaviyo", "fields": [ { "name": "account_name", "type": "string", "required": true, "sensitive": false }, { "name": "api_key", "type": "string", "required": true, "sensitive": true } ] }

Important notes

The connect_url contains a temporary access token that signs in to your Windsor.ai account. Treat it like a password: do not share it or store it in logs. The link expires automatically after 4 days; request the endpoint again to get a fresh one. Fields marked “sensitive”: true are secrets (passwords, tokens, API keys). Never display or log values entered for these fields. Requesting an unknown connector ID returns a 404 error.

List connected accounts

This endpoint returns all data source accounts connected to your Windsor.ai workspace.

You can query a specific data source or request all accounts.

List accounts for all data sources

Endpoint:

https://onboard.windsor.ai/api/common/ds-accounts?datasource=all

Example response (simplified):

[ { "datasource": "google_ads", "account_name": "ACME Google Ads", "account_id": "123-456-7890", "status": "active" }, { "datasource": "facebook", "account_name": "ACME Facebook Ads", "account_id": "987654321", "status": "active" } ]

List accounts for a specific data source

Endpoint:

https://onboard.windsor.ai/api/common/ds-accounts?datasource={SOURCE}

Example (Facebook Ads data source):

https://onboard.windsor.ai/api/common/ds-accounts?datasource=facebook

Returns only Facebook Ads accounts connected to the workspace.

Custom fields API

This endpoint returns custom fields defined in your Windsor.ai workspace.

These fields can be used in queries or enrichments across supported data sources.

List all custom fields

Endpoint:

https://onboard.windsor.ai/api/custom-fields

These fields are available immediately after creation and can be referenced in API queries.

Example use cases

Retrieving campaign performance

https://connectors.windsor.ai/facebook?fields=date,campaign,spend,impressions,clicks&date_preset=last_30d&api_key={your_api_key}

Comparing multiple platforms

https://connectors.windsor.ai/all?fields=date,source,spend,impressions,clicks&date_preset=last_30d&api_key={your_api_key}

Getting e-commerce conversion data

https://connectors.windsor.ai/googleanalytics4?fields=date,campaign,transactions,revenue&date_preset=last_30d&api_key={your_api_key}

Best practices

  1. Request only needed fields
  2. Use date presets when possible
  3. Implement caching
  4. Always handle errors with care

User agent

When making API requests to Windsor.ai connectors, the system identifies itself using the following user agent:

Windsor/1.0

This user agent is automatically included in all API requests made through our official SDKs and libraries. If you’re building custom integrations or directly interacting with our API, we recommend including this user agent in your requests for better tracking and support.

Support

If you encounter any issues or have questions about using our API, please contact our support team at [email protected] or visit our Help Center.

Changelog

2026-07-27

  • Unlinking of co-user linked accounts added

2026-07-03

  • Connector connect-info endpoint added

2026-02-24

  • Co-user linked accounts endpoint added

2025-11-13

  • Creation of authorization links added

2025-04-02

  • Added information about different renderers

2025-03-18

  • Added information about the user agent

2025-03-17

  • Initial API documentation release