Access the PostHog API with managed authentication. Query product analytics events with HogQL, manage feature flags, analyze user behavior, view session recordings, and run A/B experiments.
# List projects
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/posthog/api/projects/')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
https://api.maton.ai/posthog/{native-api-path}
Maton proxies requests to {subdomain}.posthog.com and automatically injects your credentials.
All requests require the Maton API key in the Authorization header:
Authorization: Bearer $MATON_API_KEY
Environment Variable: Set your API key as MATON_API_KEY:
export MATON_API_KEY="YOUR_API_KEY"
Manage your PostHog OAuth connections at https://api.maton.ai.
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections?app=posthog&status=ACTIVE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
python <<'EOF'
import urllib.request, os, json
data = json.dumps({'app': 'posthog'}).encode()
req = urllib.request.Request('https://api.maton.ai/connections', data=data, method='POST')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Content-Type', 'application/json')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
Response:
{
"connection": {
"connection_id": "{connection_id}",
"status": "ACTIVE",
"creation_time": "2026-02-23T09:37:57.686121Z",
"last_updated_time": "2026-02-23T09:39:11.851118Z",
"url": "https://connect.maton.ai/?session_token=...",
"app": "posthog",
"metadata": {}
}
}
Open the returned url in a browser to complete OAuth authorization.
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/connections/{connection_id}', method='DELETE')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If you have multiple PostHog connections, specify which one to use with the Maton-Connection header:
python <<'EOF'
import urllib.request, os, json
req = urllib.request.Request('https://api.maton.ai/posthog/api/projects/')
req.add_header('Authorization', f'Bearer {os.environ["MATON_API_KEY"]}')
req.add_header('Maton-Connection', '{connection_id}')
print(json.dumps(json.load(urllib.request.urlopen(req)), indent=2))
EOF
If you have multiple connections, always include this header to ensure requests go to the intended account.
GET /posthog/api/organizations/@current/
GET /posthog/api/projects/
Response:
{
"count": 1,
"next": null,
"previous": null,
"results": [
{
"id": 136209,
"uuid": "019583c6-377c-0000-e55c-8696cbc33595",
"organization": "019583c6-3635-0000-5798-c18f20963b3b",
"api_token": "phc_XXX",
"name": "Default project",
"timezone": "UTC"
}
]
}
GET /posthog/api/projects/@current/
GET /posthog/api/users/@me/
The query endpoint is the recommended way to retrieve events and run analytics queries.
POST /posthog/api/projects/{project_id}/query/
Content-Type: application/json
{
"query": {
"kind": "HogQLQuery",
"query": "SELECT event, count() FROM events GROUP BY event ORDER BY count() DESC LIMIT 10"
}
}
Response:
{
"columns": ["event", "count()"],
"results": [
["$pageview", 140504],
["$autocapture", 108691],
["$identify", 5455]
],
"types": [
["event", "String"],
["count()", "UInt64"]
]
}
GET /posthog/api/projects/{project_id}/persons/?limit=10
Response:
{
"results": [
{
"id": "5d79eecb-93e6-5c8b-90f9-8510ba4040b8",
"uuid": "5d79eecb-93e6-5c8b-90f9-8510ba4040b8",
"name": "user@example.com",
"is_identified": true,
"distinct_ids": ["user-uuid", "anon-uuid"],
"properties": {
"email": "user@example.com",
"name": "John Doe"
}
}
],
"next": "https://us.posthog.com/api/projects/{project_id}/persons/?limit=10&offset=10"
}
GET /posthog/api/projects/{project_id}/persons/{person_uuid}/
GET /posthog/api/projects/{project_id}/dashboards/
GET /posthog/api/projects/{project_id}/dashboards/{dashboard_id}/
POST /posthog/api/projects/{project_id}/dashboards/
Content-Type: application/json
{
"name": "My Dashboard",
"description": "Analytics overview"
}
PATCH /posthog/api/projects/{project_id}/dashboards/{dashboard_id}/
Content-Type: application/json
{
"name": "Updated Dashboard Name"
}
GET /posthog/api/projects/{project_id}/insights/?limit=10
GET /posthog/api/projects/{project_id}/insights/{insight_id}/
POST /posthog/api/projects/{project_id}/insights/
Content-Type: application/json
{
"name": "Daily Active Users",
"query": {
"kind": "InsightVizNode",
"source": {
"kind": "TrendsQuery",
"series": [{"kind": "EventsNode", "event": "$pageview", "math": "dau"}],
"interval": "day",
"dateRange": {"date_from": "-30d"}
}
}
}
GET /posthog/api/projects/{project_id}/feature_flags/
GET /posthog/api/projects/{project_id}/feature_flags/{flag_id}/
POST /posthog/api/projects/{project_id}/feature_flags/
Content-Type: application/json
{
"key": "my-feature-flag",
"name": "My Feature Flag",
"active": true,
"filters": {
"groups": [{"rollout_percentage": 100}]
}
}
PATCH /posthog/api/projects/{project_id}/feature_flags/{flag_id}/
Content-Type: application/json
{
"active": false
}
Use soft delete by setting deleted: true:
PATCH /posthog/api/projects/{project_id}/feature_flags/{flag_id}/
Content-Type: application/json
{
"deleted": true
}
GET /posthog/api/projects/{project_id}/cohorts/
GET /posthog/api/projects/{project_id}/cohorts/{cohort_id}/
POST /posthog/api/projects/{project_id}/cohorts/
Content-Type: application/json
{
"name": "Active Users",
"groups": [
{
"properties": [
{"key": "$pageview", "type": "event", "value": "performed_event"}
]
}
]
}
GET /posthog/api/projects/{project_id}/actions/
POST /posthog/api/projects/{project_id}/actions/
Content-Type: application/json
{
"name": "Signed Up",
"steps": [{"event": "$identify"}]
}
GET /posthog/api/projects/{project_id}/session_recordings/?limit=10
Response:
{
"results": [
{
"id": "019c8795-79e3-7a05-ac56-597b102f1960",
"distinct_id": "user-uuid",
"recording_duration": 1807,
"start_time": "2026-02-22T23:00:46.389000Z",
"end_time": "2026-02-22T23:30:53.297000Z",
"click_count": 0,
"keypress_count": 0,
"start_url": "https://example.com/register"
}
],
"has_next": false
}
GET /posthog/api/projects/{project_id}/session_recordings/{recording_id}/
GET /posthog/api/projects/{project_id}/annotations/
POST /posthog/api/projects/{project_id}/annotations/
Content-Type: application/json
{
"content": "New feature launched",
"date_marker": "2026-02-23T00:00:00Z",
"scope": "project"
}
GET /posthog/api/projects/{project_id}/surveys/
POST /posthog/api/projects/{project_id}/surveys/
Content-Type: application/json
{
"name": "NPS Survey",
"type": "popover",
"questions": [
{
"type": "rating",
"question": "How likely are you to recommend us?"
}
]
}
GET /posthog/api/projects/{project_id}/experiments/
POST /posthog/api/projects/{project_id}/experiments/
Content-Type: application/json
{
"name": "Button Color Test",
"feature_flag_key": "button-color-test"
}
GET /posthog/api/projects/{project_id}/event_definitions/?limit=10
GET /posthog/api/projects/{project_id}/property_definitions/?limit=10
PostHog uses offset-based pagination:
GET /posthog/api/projects/{project_id}/persons/?limit=10&offset=20
Response includes pagination info:
{
"count": 100,
"next": "https://us.posthog.com/api/projects/{project_id}/persons/?limit=10&offset=30",
"previous": "https://us.posthog.com/api/projects/{project_id}/persons/?limit=10&offset=10",
"results": [...]
}
For session recordings, use has_next boolean:
{
"results": [...],
"has_next": true
}
const response = await fetch(
'https://api.maton.ai/posthog/api/projects/',
{
headers: {
'Authorization': `Bearer ${process.env.MATON_API_KEY}`
}
}
);
const data = await response.json();
import os
import requests
response = requests.get(
'https://api.maton.ai/posthog/api/projects/',
headers={'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}'}
)
data = response.json()
import os
import requests
response = requests.post(
'https://api.maton.ai/posthog/api/projects/@current/query/',
headers={
'Authorization': f'Bearer {os.environ["MATON_API_KEY"]}',
'Content-Type': 'application/json'
},
json={
'query': {
'kind': 'HogQLQuery',
'query': 'SELECT event, count() FROM events GROUP BY event LIMIT 10'
}
}
)
data = response.json()
@current as a shortcut for the current project ID (e.g., /api/projects/@current/dashboards/)136209)PATCH with {"deleted": true} instead of HTTP DELETEjq or other commands, environment variables like $MATON_API_KEY may not expand correctly in some shell environments. Use Python examples instead.| Status | Meaning |
|---|---|
| -------- | --------- |
| 400 | Missing PostHog connection |
| 401 | Invalid or missing Maton API key |
| 429 | Rate limited |
| 4xx/5xx | Passthrough error from PostHog API |
共 2 个版本