External Data

For instructions on how to authenticate to use this endpoint, see API overview.

Endpoints

GET
POST
GET
PATCH
DELETE
PATCH
GET
POST
POST
POST
GET
PATCH
POST
POST
GET
POST
POST
POST
POST

List all external data sources

Also available via the PostHog MCP server:

  • external-data-sources-list — List data warehouse sources

Create, Read, Update and Delete External data Sources.

Required API key scopes

external_data_source:read

Query parameters

  • limit
    integer
  • offset
    integer
  • search
    string

Response


Example request

GET /api/projects/:project_id/external_data_sources
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/external_data_sources/

Example response

Status 200
RESPONSE
{
"count": 123,
"next": "http://api.example.org/accounts/?offset=400&limit=100",
"previous": "http://api.example.org/accounts/?offset=200&limit=100",
"results": [
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"created_at": "2019-08-24T14:15:22Z",
"created_by": "string",
"created_via": "web",
"status": "string",
"client_secret": "string",
"account_id": "string",
"source_type": "Ashby",
"latest_error": "string",
"prefix": "string",
"description": "string",
"access_method": "warehouse",
"direct_query_enabled": true,
"auto_sync_new_schemas": true,
"auto_sync_schema_patterns": [
"string"
],
"engine": "duckdb",
"last_run_at": "string",
"schemas": [
{}
],
"job_inputs": null,
"revenue_analytics_config": {
"enabled": true,
"include_invoiceless_charges": true
},
"user_access_level": "string",
"supports_webhooks": true,
"supports_column_selection": true,
"api_version": "string",
"api_version_deprecation": {
"version": "string",
"sunset_at": "2019-08-24",
"default_version": "string"
},
"connection_warning": "string"
}
]
}

Create external data sources

Also available via the PostHog MCP server:

  • external-data-sources-create — Create data warehouse source (advanced; prefer source setup)

Create, Read, Update and Delete External data Sources.

Required API key scopes

external_data_source:write

Request parameters

  • source_type
  • payload
    object
  • prefix
    string | null
  • description
    string | null
  • access_method
    Default: warehouse
  • created_via
    Default: api
  • direct_query_enabled
    boolean
    Default: false
  • destination_ids
    array

Response


Example request

POST /api/projects/:project_id/external_data_sources
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/external_data_sources/\
-d source_type=undefined,\
-d payload="object"

Example response

Status 201
RESPONSE
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08"
}

Retrieve external data sources

Also available via the PostHog MCP server:

  • external-data-sources-retrieve — Get data warehouse source

Create, Read, Update and Delete External data Sources.

Required API key scopes

external_data_source:read

Path parameters

  • id
    string

Response


Example request

GET /api/projects/:project_id/external_data_sources/:id
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/external_data_sources/:id/

Example response

Status 200
RESPONSE
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"created_at": "2019-08-24T14:15:22Z",
"created_by": "string",
"created_via": "web",
"status": "string",
"client_secret": "string",
"account_id": "string",
"source_type": "Ashby",
"latest_error": "string",
"prefix": "string",
"description": "string",
"access_method": "warehouse",
"direct_query_enabled": true,
"auto_sync_new_schemas": true,
"auto_sync_schema_patterns": [
"string"
],
"engine": "duckdb",
"last_run_at": "string",
"schemas": [
{}
],
"job_inputs": null,
"revenue_analytics_config": {
"enabled": true,
"include_invoiceless_charges": true
},
"user_access_level": "string",
"supports_webhooks": true,
"supports_column_selection": true,
"api_version": "string",
"api_version_deprecation": {
"version": "string",
"sunset_at": "2019-08-24",
"default_version": "string"
},
"connection_warning": "string"
}

Update external data sources

Also available via the PostHog MCP server:

  • external-data-sources-partial-update — Update data warehouse source

Create, Read, Update and Delete External data Sources.

Required API key scopes

external_data_source:write

Path parameters

  • id
    string

Request parameters

  • created_via
  • client_secret
    string
  • account_id
    string
  • prefix
    string | null
  • description
    string | null
  • direct_query_enabled
    boolean
  • auto_sync_new_schemas
    boolean
  • auto_sync_schema_patterns
    array | null
  • job_inputs

Response


Example request

PATCH /api/projects/:project_id/external_data_sources/:id
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl -X PATCH \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/external_data_sources/:id/\
-d created_at="string"

Example response

Status 200
RESPONSE
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"created_at": "2019-08-24T14:15:22Z",
"created_by": "string",
"created_via": "web",
"status": "string",
"client_secret": "string",
"account_id": "string",
"source_type": "Ashby",
"latest_error": "string",
"prefix": "string",
"description": "string",
"access_method": "warehouse",
"direct_query_enabled": true,
"auto_sync_new_schemas": true,
"auto_sync_schema_patterns": [
"string"
],
"engine": "duckdb",
"last_run_at": "string",
"schemas": [
{}
],
"job_inputs": null,
"revenue_analytics_config": {
"enabled": true,
"include_invoiceless_charges": true
},
"user_access_level": "string",
"supports_webhooks": true,
"supports_column_selection": true,
"api_version": "string",
"api_version_deprecation": {
"version": "string",
"sunset_at": "2019-08-24",
"default_version": "string"
},
"connection_warning": "string"
}

Delete external data sources

Also available via the PostHog MCP server:

  • external-data-sources-destroy — Delete data warehouse source

Create, Read, Update and Delete External data Sources.

Required API key scopes

external_data_source:write

Path parameters

  • id
    string

Example request

DELETE /api/projects/:project_id/external_data_sources/:id
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl -X DELETE \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/external_data_sources/:id/

Example response

Status 204 No response body

Update external data sources bulk update schemas

Create, Read, Update and Delete External data Sources.

Required API key scopes

external_data_source:write

Path parameters

  • id
    string

Request parameters

  • schemas
    Click to open
    array

Example request

PATCH /api/projects/:project_id/external_data_sources/:id/bulk_update_schemas
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl -X PATCH \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/external_data_sources/:id/bulk_update_schemas/\
-d schemas="array"

Example response

Status 200
RESPONSE
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"name": "string",
"label": "string",
"table": {},
"should_sync": true,
"last_synced_at": "2019-08-24T14:15:22Z",
"latest_error": "string",
"incremental": true,
"status": "string",
"sync_type": "full_refresh",
"incremental_field": "string",
"incremental_field_type": "integer",
"incremental_field_lookback_seconds": 5184000,
"sync_frequency": "never",
"sync_time_of_day": "14:15:22Z",
"full_refresh_interval_days": 1,
"full_refresh_time_of_day": "14:15:22Z",
"next_full_refresh_at": "2019-08-24T14:15:22Z",
"description": "string",
"primary_key_columns": [
"string"
],
"cdc_table_mode": "consolidated",
"incremental_sync_blocked": "missing_primary_key",
"enabled_columns": [
"string"
],
"row_filters": [
{
"column": "string",
"operator": "string",
"value": null
}
],
"row_filter_columns": [
{
"name": "string",
"data_type": "string",
"operators": [
"string"
]
}
],
"available_columns": [
{
"name": "string",
"data_type": "string",
"is_nullable": true
}
],
"source_column_metadata_available": true,
"source": {
"id": "string",
"source_type": "string",
"access_method": "string",
"supports_column_selection": true,
"supports_row_filters": true,
"requires_exact_column_metadata": true,
"user_access_level": "string",
"api_version": "string",
"supported_api_versions": [
"string"
]
},
"api_version": "string",
"api_version_deprecation": {
"version": "string",
"sunset_at": "2019-08-24",
"default_version": "string"
},
"user_access_level": "string"
}

Retrieve external data sources cdc status

Live CDC health for an existing source: slot/publication existence and WAL lag.

Reads from the source DB via the engine adapter. Returns {"enabled": false} when CDC is off, or the stored config plus live slot_exists / publication_exists / lag_bytes when on. 400s if the source DB is unreachable so the UI can show a degraded/unreachable state.

Required API key scopes

external_data_source:read

Path parameters

  • id
    string

Response


Example request

GET /api/projects/:project_id/external_data_sources/:id/cdc_status
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/external_data_sources/:id/cdc_status/

Example response

Status 200
RESPONSE
{
"enabled": true,
"management_mode": "posthog",
"slot_name": "string",
"publication_name": "string",
"lag_warning_threshold_mb": 0,
"lag_critical_threshold_mb": 0,
"schedule_paused": true,
"slot_exists": true,
"publication_exists": true,
"lag_bytes": 0,
"published_tables": [
"string"
]
}

Create external data sources check cdc prerequisites for source

Validate CDC prerequisites for an existing source using its stored credentials.

The detail=False check_cdc_prerequisites action is for the creation wizard, where the client still holds the raw connection config (incl. password) in the form. On the Configuration page the source already exists and secret fields are stripped from API responses — so the client can't supply them. This reads the stored (encrypted) credentials from the DB via the adapter instead.

Body params: cdc_management_mode ("posthog" | "self_managed"), cdc_slot_name (optional), cdc_publication_name (optional).

Required API key scopes

external_data_source:write

Path parameters

  • id
    string

Request parameters

  • created_via
  • client_secret
    string
  • account_id
    string
  • prefix
    string | null
  • description
    string | null
  • direct_query_enabled
    boolean
  • auto_sync_new_schemas
    boolean
  • auto_sync_schema_patterns
    array | null
  • job_inputs

Example request

POST /api/projects/:project_id/external_data_sources/:id/check_cdc_prerequisites_for_source
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/external_data_sources/:id/check_cdc_prerequisites_for_source/\
-d client_secret="string",\
-d account_id="string"

Example response

Status 200 No response body

Create external data sources create webhook

Also available via the PostHog MCP server:

  • external-data-sources-create-webhook-create — Create and register a webhook for a source

Create, Read, Update and Delete External data Sources.

Required API key scopes

external_data_source:write

Path parameters

  • id
    string

Request parameters

  • created_via
  • client_secret
    string
  • account_id
    string
  • prefix
    string | null
  • description
    string | null
  • direct_query_enabled
    boolean
  • auto_sync_new_schemas
    boolean
  • auto_sync_schema_patterns
    array | null
  • job_inputs

Response


Example request

POST /api/projects/:project_id/external_data_sources/:id/create_webhook
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/external_data_sources/:id/create_webhook/\
-d client_secret="string",\
-d account_id="string"

Example response

Status 200
RESPONSE
{
"success": true,
"webhook_url": "string",
"error": "string",
"pending_inputs": [
"string"
]
}

Create external data sources delete webhook

Also available via the PostHog MCP server:

  • external-data-sources-delete-webhook-create — Delete a source's webhook

Create, Read, Update and Delete External data Sources.

Required API key scopes

external_data_source:write

Path parameters

  • id
    string

Request parameters

  • created_via
  • client_secret
    string
  • account_id
    string
  • prefix
    string | null
  • description
    string | null
  • direct_query_enabled
    boolean
  • auto_sync_new_schemas
    boolean
  • auto_sync_schema_patterns
    array | null
  • job_inputs

Response


Example request

POST /api/projects/:project_id/external_data_sources/:id/delete_webhook
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/external_data_sources/:id/delete_webhook/\
-d client_secret="string",\
-d account_id="string"

Example response

Status 200
RESPONSE
{
"success": true,
"external_deleted": true,
"error": "string"
}

Retrieve external data sources destinations

Read or replace the destinations every table on this source syncs to.

A table with its own override ignores this set until the override is cleared.

Required API key scopes

external_data_source:write

Path parameters

  • id
    string

Response


Example request

GET /api/projects/:project_id/external_data_sources/:id/destinations
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/external_data_sources/:id/destinations/

Example response

Status 200
RESPONSE
{
"destination_ids": [
"497f6eca-6276-4993-bfeb-53cbbbba6f08"
]
}

Update external data sources destinations

Read or replace the destinations every table on this source syncs to.

A table with its own override ignores this set until the override is cleared.

Required API key scopes

external_data_source:write

Path parameters

  • id
    string

Request parameters

  • destination_ids
    array | null

Response


Example request

PATCH /api/projects/:project_id/external_data_sources/:id/destinations
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl -X PATCH \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/external_data_sources/:id/destinations/\
-d destination_ids="array"

Example response

Status 200
RESPONSE
{
"destination_ids": [
"497f6eca-6276-4993-bfeb-53cbbbba6f08"
]
}

Create external data sources disable cdc

Disable CDC on an existing source.

Cancels any running CDC extraction workflow, deletes the extraction schedule, delegates engine-side teardown to the source's adapter (drops slot/publication for Postgres; equivalent for other engines), clears cdc_* keys from job_inputs, soft-deletes companion CDC tables, and sets all CDC schemas to sync_type=None, should_sync=False so the user must pick a new sync strategy before they resume.

Required API key scopes

external_data_source:write

Path parameters

  • id
    string

Request parameters

  • created_via
  • client_secret
    string
  • account_id
    string
  • prefix
    string | null
  • description
    string | null
  • direct_query_enabled
    boolean
  • auto_sync_new_schemas
    boolean
  • auto_sync_schema_patterns
    array | null
  • job_inputs

Example request

POST /api/projects/:project_id/external_data_sources/:id/disable_cdc
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/external_data_sources/:id/disable_cdc/\
-d client_secret="string",\
-d account_id="string"

Example response

Status 200 No response body

Create external data sources enable cdc

Enable CDC on an existing source.

Provisions engine-side CDC resources via the source's adapter, writes the CDC config into source.job_inputs, and ensures the CDC extraction schedule exists. Re-runs prereq checks server-side so we never trust a stale client-side check.

Body params: cdc_management_mode ("posthog" | "self_managed"), plus engine-specific identifier hints (e.g. cdc_slot_name, cdc_publication_name for Postgres). Universal tuning fields: cdc_auto_drop_slot (optional bool), cdc_lag_warning_threshold_mb (optional int), cdc_lag_critical_threshold_mb (optional int).

Required API key scopes

external_data_source:write

Path parameters

  • id
    string

Request parameters

  • created_via
  • client_secret
    string
  • account_id
    string
  • prefix
    string | null
  • description
    string | null
  • direct_query_enabled
    boolean
  • auto_sync_new_schemas
    boolean
  • auto_sync_schema_patterns
    array | null
  • job_inputs

Response


Example request

POST /api/projects/:project_id/external_data_sources/:id/enable_cdc
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/external_data_sources/:id/enable_cdc/\
-d client_secret="string",\
-d account_id="string"

Example response

Status 200
RESPONSE
{
"success": true,
"schedules_ready": true
}

List all external data sources jobs

Create, Read, Update and Delete External data Sources.

Required API key scopes

external_data_source:read

Path parameters

  • id
    string

Query parameters

  • after
    string
  • before
    string
  • schemas
    array
  • search
    string

Example request

GET /api/projects/:project_id/external_data_sources/:id/jobs
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl \
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/external_data_sources/:id/jobs/

Example response

Status 200
RESPONSE
{
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"created_at": "2019-08-24T14:15:22Z",
"created_by": 0,
"finished_at": "2019-08-24T14:15:22Z",
"status": "string",
"schema": {
"id": "497f6eca-6276-4993-bfeb-53cbbbba6f08",
"name": "string",
"label": "string",
"should_sync": true,
"last_synced_at": "2019-08-24T14:15:22Z",
"sync_type": "full_refresh"
},
"rows_synced": 0,
"latest_error": "string",
"workflow_run_id": "string",
"cdc_write_mode": "string",
"billable": true,
"destination_ids": [
"string"
]
}

Create external data sources refresh schemas

Fetch current schema/table list from the source and create any new ExternalDataSchema rows (no data sync).

Required API key scopes

external_data_source:write

Path parameters

  • id
    string

Request parameters

  • created_via
  • client_secret
    string
  • account_id
    string
  • prefix
    string | null
  • description
    string | null
  • direct_query_enabled
    boolean
  • auto_sync_new_schemas
    boolean
  • auto_sync_schema_patterns
    array | null
  • job_inputs

Example request

POST /api/projects/:project_id/external_data_sources/:id/refresh_schemas
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/external_data_sources/:id/refresh_schemas/\
-d client_secret="string",\
-d account_id="string"

Example response

Status 200 No response body

Create external data sources reload

Create, Read, Update and Delete External data Sources.

Required API key scopes

external_data_source:write

Path parameters

  • id
    string

Request parameters

  • created_via
  • client_secret
    string
  • account_id
    string
  • prefix
    string | null
  • description
    string | null
  • direct_query_enabled
    boolean
  • auto_sync_new_schemas
    boolean
  • auto_sync_schema_patterns
    array | null
  • job_inputs

Example request

POST /api/projects/:project_id/external_data_sources/:id/reload
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/external_data_sources/:id/reload/\
-d client_secret="string",\
-d account_id="string"

Example response

Status 200 No response body

Create external data sources repair cdc

Repair CDC on a source whose replication resources were lost.

Only proceeds on evidence of breakage (a persisted broken marker, or a live probe showing the slot/publication missing) — repairing a healthy source would drop its slot and force a full re-sync. Cancels running CDC jobs, recreates the engine-side slot/publication against the stored CDC config, resets every active CDC schema to snapshot mode for a full re-sync (changes since the old slot died are unrecoverable), clears the broken markers, and resumes the paused schedules. Idempotent: safe to retry after a partial failure. Concurrent repairs of the same source are rejected with a 409.

Required API key scopes

external_data_source:write

Path parameters

  • id
    string

Example request

POST /api/projects/:project_id/external_data_sources/:id/repair_cdc
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/external_data_sources/:id/repair_cdc/

Example response

Status 200 CDC repaired; schemas_reset CDC schemas will fully re-sync.
Status 400 CDC not enabled, no active CDC schemas, source looks healthy, or engine-side recreation failed.
Status 409 A repair is already running for this source.

Create external data sources resume cdc

Resume a CDC source whose extraction schedule was paused by a non-retryable failure that left the replication slot intact (bad credentials, SSL/host errors).

Once the user has fixed the root cause, this re-probes the source DB — confirming the connection now succeeds and the slot/publication still exist — then unpauses the extraction schedule so streaming resumes from where it left off. No re-snapshot, so it's the cheap counterpart to Repair CDC. If the slot/publication are actually gone (cdc_broken, or a live probe showing them missing), resume is refused — only Repair CDC can recreate them, at the cost of a full re-sync.

Path parameters

  • id
    string

Example request

POST /api/projects/:project_id/external_data_sources/:id/resume_cdc
export POSTHOG_PERSONAL_API_KEY=[your personal api key]
curl
-H 'Content-Type: application/json'\
-H "Authorization: Bearer $POSTHOG_PERSONAL_API_KEY" \
<ph_app_host>/api/projects/:project_id/external_data_sources/:id/resume_cdc/

Example response

Status 200 CDC resumed; the extraction schedule is unpaused.
Status 400 CDC not enabled, the slot/publication were lost (use Repair CDC), the source is still unreachable, or unpausing failed.