# Bulk Create Attributions
Source: https://docs.finseo.ai/api-reference/attribution/bulk
POST /v1/projects/{projectId}/attribution/bulk
Import up to 1000 attribution responses at once. Use this for historical data migration from your CRM or analytics tool.
Requires `write` scope on your API key.
The project ID.
Array of attribution responses (max 1000). Each item requires at least `channelId`.
```bash cURL theme={"system"}
curl --request POST \
--url https://api.finseo.ai/v1/projects/PROJECT_ID/attribution/bulk \
--header "Authorization: Bearer $FINSEO_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"responses": [
{
"channelId": "ai_search",
"respondentEmail": "jane@company.com",
"dealValue": 12000
},
{
"channelId": "google_search",
"respondentEmail": "john@corp.com",
"dealValue": 8500
},
{
"channelId": "social_media",
"respondentEmail": "alex@startup.io"
}
]
}'
```
```json theme={"system"}
{
"data": {
"imported": 3
}
}
```
# List Attributions
Source: https://docs.finseo.ai/api-reference/attribution/list
GET /v1/projects/{projectId}/attribution
Get paginated attribution survey responses for a project. Filter by channel category, source, and time range.
The project ID.
Number of days to look back.
Filter by channel category: `ai_search`, `organic_search`, `paid`, `social`, `referral`, `content`, `direct`, `other`.
Filter by data source: `widget`, `hubspot`, `typeform`, `jotform`, `salesforce`, `api`, `api_bulk`.
Page number.
Results per page (max 500).
```bash cURL theme={"system"}
curl --request GET \
--url 'https://api.finseo.ai/v1/projects/PROJECT_ID/attribution?days=30&category=ai_search' \
--header "Authorization: Bearer $FINSEO_API_KEY"
```
```json theme={"system"}
{
"data": {
"responses": [
{
"id": "a1b2c3d4-...",
"channel_id": "ai_search",
"channel_label": "AI Search (ChatGPT, Perplexity, etc.)",
"channel_category": "ai_search",
"respondent_email": "jane@company.com",
"respondent_name": "Jane Smith",
"deal_value": 12000,
"deal_currency": "USD",
"source": "hubspot",
"page_url": "https://example.com/signup",
"form_id": "lT4Z3j",
"created_at": "2026-03-15T10:30:00Z"
}
],
"meta": {
"page": 1,
"limit": 50,
"total": 142,
"hasMore": true
}
}
}
```
# Create Attribution
Source: https://docs.finseo.ai/api-reference/attribution/submit
POST /v1/projects/{projectId}/attribution
Record a self-reported attribution response. Use this to track how customers discovered your brand — from AI search, organic, social, ads, referrals, or any custom channel.
Requires `write` scope on your API key.
The project ID.
Attribution channel identifier. Use standard IDs like `ai_search`, `ai_chatgpt`, `ai_perplexity`, `google_search`, `social_media`, `paid_ads`, `referral`, `content`, or any custom string.
Lead email address.
Lead full name.
External ID from your CRM or system.
Revenue amount attributed to this lead.
ISO currency code.
Identifier of the source form (e.g. Typeform form\_id, HubSpot form ID).
Page URL where the form was submitted.
Additional custom data as key-value pairs.
```bash cURL theme={"system"}
curl --request POST \
--url https://api.finseo.ai/v1/projects/PROJECT_ID/attribution \
--header "Authorization: Bearer $FINSEO_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"channelId": "ai_search",
"respondentEmail": "jane@company.com",
"respondentName": "Jane Smith",
"dealValue": 12000,
"dealCurrency": "EUR",
"formId": "signup_form_v2",
"pageUrl": "https://example.com/signup"
}'
```
```json theme={"system"}
{
"data": {
"id": "a1b2c3d4-...",
"channel_id": "ai_search",
"channel_label": "AI Search (ChatGPT, Perplexity, etc.)",
"channel_category": "ai_search",
"respondent_email": "jane@company.com",
"deal_value": 12000,
"source": "api",
"created_at": "2026-03-15T10:30:00Z"
}
}
```
# Get Attribution Summary
Source: https://docs.finseo.ai/api-reference/attribution/summary
GET /v1/projects/{projectId}/attribution/summary
Get aggregated attribution data showing channel breakdown, AI search percentage, and total attributed revenue. Use this to understand what percentage of your leads come from AI search vs other channels.
The project ID.
Number of days to look back.
```bash cURL theme={"system"}
curl --request GET \
--url 'https://api.finseo.ai/v1/projects/PROJECT_ID/attribution/summary?days=30' \
--header "Authorization: Bearer $FINSEO_API_KEY"
```
```json theme={"system"}
{
"data": {
"total": 142,
"totalRevenue": 580000,
"aiSearchPercentage": 34.5,
"byCategory": [
{ "category": "ai_search", "count": 49, "revenue": 245000, "percentage": 34.5 },
{ "category": "organic_search", "count": 38, "revenue": 152000, "percentage": 26.8 },
{ "category": "social", "count": 22, "revenue": 88000, "percentage": 15.5 },
{ "category": "paid", "count": 18, "revenue": 54000, "percentage": 12.7 },
{ "category": "referral", "count": 15, "revenue": 41000, "percentage": 10.6 }
],
"bySource": [
{ "source": "widget", "count": 68 },
{ "source": "hubspot", "count": 42 },
{ "source": "api", "count": 32 }
]
}
}
```
# List Competitors
Source: https://docs.finseo.ai/api-reference/competitors/ranking
GET /v1/projects/{projectId}/competitors
Returns ranked competitors for AI visibility: visibility, mention rate, citation rate, mentions, Share of Voice, position, and sentiment. Use this to see how Finseo stacks up against other brands in ChatGPT, Claude, and Perplexity answers.
Three presence rates are returned per competitor, all as a share of `totalResults` (see [KPIs explained](/getting-started/kpis)):
* `visibilityRate` — **Visibility**: % of answers where the brand is visible, i.e. named in the answer text OR its domain cited as a source (the dashboard "Visibility" column; `visibleResults` is the count). `visibilityIsMentionOnly: true` flags rows where the citation leg could not be resolved and the value equals the mention-based rate.
* `mentionRate` — **Mention Rate**: % of answers naming the brand in the text (`totalMentions` is the count).
* `citationRate` — **Citation Rate**: % of answers citing the brand's domain as a source (`totalCitations` is the count); `null` when citations could not be resolved for the brand.
One answer can count toward both `mentionRate` and `citationRate`, so `visibilityRate ≤ mentionRate + citationRate`.
Two position metrics are returned per competitor:
* `avgMentionOrder` — the ordinal **Position** KPI: average rank among all brands named in an answer (1 = named first, lower is better). This is the `#2.3`-style value shown on the dashboard competitors page.
* `averagePosition` — **Mention Depth**: how deep in the answer *text* the mention appears (0% = very top). Not a ranking position; kept under this name for backwards compatibility.
Project identifier.
Analysis window, e.g. `7d`, `30d`. Ignored when `startDate`/`endDate` are set.
Custom range start (`YYYY-MM-DD`). Must be combined with `endDate`; overrides `timeframe`.
Custom range end (`YYYY-MM-DD`). Must be combined with `startDate`.
Filter tracking results to one model.
Filter prompts by language.
JSON array or comma-separated prompt tags.
Filter by competitor name or domain substring.
One of `visibility` (named OR cited), `mentions`, `position`, `sentiment`, `name`.
`asc` or `desc`.
Page number.
Page size (1–500).
```bash cURL theme={"system"}
curl --request GET \
--url 'https://api.finseo.ai/v1/projects/67a1c2d3e4f5061728394a5b/competitors?timeframe=30d&sortBy=mentions&limit=20' \
--header "Authorization: Bearer $FINSEO_API_KEY"
```
```python Python theme={"system"}
import requests
r = requests.get(
"https://api.finseo.ai/v1/projects/67a1c2d3e4f5061728394a5b/competitors",
headers={"Authorization": "Bearer sk_live_xxxxxxxx"},
params={"timeframe": "30d", "sortBy": "visibility", "limit": 20},
)
competitors = r.json()["data"]["competitors"]
print([c["name"] for c in competitors if c["isUserBrand"]])
```
```json theme={"system"}
{
"data": {
"competitors": [
{
"id": "c7d8e9f0-a1b2-4345-cdef-678901234abc",
"name": "Finseo",
"domain": "finseo.ai",
"baseDomain": "finseo.ai",
"isStarred": true,
"isUserBrand": true,
"totalMentions": 186,
"visibleResults": 214,
"totalResults": 420,
"visibilityRate": 51.0,
"visibilityChange": 4.2,
"visibilityIsMentionOnly": false,
"mentionRate": 44.3,
"mentionRateChange": 2.1,
"totalCitations": 98,
"citationRate": 23.3,
"citationRateChange": 3.8,
"avgMentionOrder": 2.3,
"avgMentionOrderChange": -0.2,
"firstMentionSharePercent": 44,
"top3MentionSharePercent": 65,
"shareOfVoicePercent": 8.2,
"shareOfVoiceChange": 0.6,
"averagePosition": 17.3,
"sentimentScore": 0.77,
"promptCount": 42
},
{
"id": "d8e9f0a1-b2c3-4456-def0-789012345bcd",
"name": "Competitor A",
"domain": "competitor-a.com",
"baseDomain": "competitor-a.com",
"isStarred": false,
"isUserBrand": false,
"totalMentions": 172,
"visibleResults": 181,
"totalResults": 420,
"visibilityRate": 43.1,
"visibilityChange": -1.4,
"visibilityIsMentionOnly": false,
"mentionRate": 41.0,
"mentionRateChange": -0.9,
"totalCitations": 24,
"citationRate": 5.7,
"citationRateChange": -0.5,
"avgMentionOrder": 3.1,
"avgMentionOrderChange": 0.4,
"firstMentionSharePercent": 23,
"top3MentionSharePercent": 53,
"shareOfVoicePercent": 4.2,
"shareOfVoiceChange": -0.3,
"averagePosition": 21.4,
"sentimentScore": 0.62,
"promptCount": 42
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 15,
"hasMore": false
}
}
}
```
# Export Project Data
Source: https://docs.finseo.ai/api-reference/export/bulk
GET /v1/projects/{projectId}/export
Exports prompts with nested tracking results for the selected timeframe. Intended for offline analysis, BI tools, or backups of Finseo AI visibility data from ChatGPT, Claude, Perplexity, and other models.
Project identifier.
Rolling window of results to include (max 1000 prompts; results bounded by date range). Ignored when `startDate`/`endDate` are set.
Custom range start (`YYYY-MM-DD`). Must be combined with `endDate`; overrides `timeframe`.
Custom range end (`YYYY-MM-DD`). Must be combined with `startDate`.
Parsed on shared schema; export handler may include all models in results.
Parsed on shared schema.
Parsed on shared schema.
Parsed on shared schema.
Parsed on shared schema.
```bash cURL theme={"system"}
curl --request GET \
--url 'https://api.finseo.ai/v1/projects/67a1c2d3e4f5061728394a5b/export?timeframe=30d' \
--header "Authorization: Bearer $FINSEO_API_KEY"
```
```python Python theme={"system"}
import requests
r = requests.get(
"https://api.finseo.ai/v1/projects/67a1c2d3e4f5061728394a5b/export",
headers={"Authorization": "Bearer sk_live_xxxxxxxx"},
params={"timeframe": "30d"},
)
export_payload = r.json()["data"]
print(export_payload["timeframeDays"], len(export_payload["prompts"]))
```
```json theme={"system"}
{
"data": {
"exportedAt": "2026-03-29T16:45:00.000Z",
"timeframeDays": 30,
"prompts": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"prompt": "Best AI visibility platforms including Finseo",
"domain": "finseo.ai",
"brandName": "finseo",
"language": "en",
"tags": ["branded", "comparison"],
"models": ["chatgpt", "claude", "perplexity"],
"resultCount": 6,
"results": [
{
"id": "r1e2s3u4-l5t6-7890-abcd-ef1234567890",
"model": "chatgpt",
"visible": true,
"mentions": 3,
"position": 2,
"percentageRank": 18.5,
"timestamp": "2026-03-28T14:02:11.000Z",
"fanOutQueries": ["AI SEO tools 2026", "Finseo reviews"]
}
]
}
]
}
}
```
# Get Fan-out Details
Source: https://docs.finseo.ai/api-reference/fanouts/details
GET /v1/projects/{projectId}/fanouts/details
Get per-occurrence details for a single fan-out query — every tracking result whose fan-out queries contain this exact text.
Returns every tracking result where this specific fan-out query was generated, including the source prompt, model, timestamp, visibility, and mentions.
Use this endpoint to drill down from the aggregated fan-out list (`GET /fanouts`) into the individual occurrences.
The project ID
The exact fan-out query text (case-insensitive match)
Time window — `7d`, `30d`, `90d`, `365d`, or `all` to search across all fan-outs ever
Custom start date (YYYY-MM-DD)
Custom end date (YYYY-MM-DD)
Comma-separated tags to filter source prompts
```bash cURL theme={"system"}
curl --request GET \
--url 'https://api.finseo.ai/v1/projects/proj_abc123/fanouts/details?query=best+CRM+for+small+business+2026&timeframe=30d' \
--header "Authorization: Bearer $FINSEO_API_KEY"
```
```python Python theme={"system"}
import requests
response = requests.get(
f"https://api.finseo.ai/v1/projects/{project_id}/fanouts/details",
headers={"Authorization": "Bearer YOUR_API_KEY"},
params={"query": "best CRM for small business 2026", "timeframe": "30d"}
)
data = response.json()["data"]
print(f"Found {data['totalOccurrences']} occurrences of '{data['query']}'")
for occ in data["occurrences"]:
print(f" {occ['model']} on {occ['timestamp']} — visible: {occ['visible']}")
```
```json 200 theme={"system"}
{
"data": {
"query": "best CRM for small business 2026",
"totalOccurrences": 47,
"occurrences": [
{
"resultId": "uuid-1",
"promptId": "prompt-uuid-1",
"promptText": "What CRM should I use for my startup?",
"brandName": "yourbrand",
"model": "chatgpt",
"timestamp": "2026-03-29T18:42:00Z",
"visible": true,
"mentions": 2
},
{
"resultId": "uuid-2",
"promptId": "prompt-uuid-2",
"promptText": "Best CRM for B2B SaaS",
"brandName": "yourbrand",
"model": "perplexity",
"timestamp": "2026-03-29T15:20:00Z",
"visible": false,
"mentions": 0
}
]
}
}
```
# List Fan-outs
Source: https://docs.finseo.ai/api-reference/fanouts/list
GET /v1/projects/{projectId}/fanouts
Get the AI query fan-outs (related sub-queries that AI models generated while answering your tracked prompts), aggregated and ranked by frequency.
Query fan-outs are related sub-queries that AI models (ChatGPT, Claude, Perplexity, etc.) generate internally while answering your tracked prompts. This endpoint aggregates them across all tracking results in a timeframe and returns them ranked by occurrence count.
This is the same data shown on the Query Fan-outs page in the Finseo dashboard.
The project ID
Time window — `7d`, `30d`, `90d`, `365d`, or `all` to get all fan-outs ever
Custom start date (YYYY-MM-DD), overrides timeframe
Custom end date (YYYY-MM-DD), overrides timeframe
Comma-separated tags to filter source prompts
Page number
Results per page (max 500)
```bash cURL theme={"system"}
curl --request GET \
--url 'https://api.finseo.ai/v1/projects/proj_abc123/fanouts?timeframe=30d&limit=20' \
--header "Authorization: Bearer $FINSEO_API_KEY"
```
```python Python theme={"system"}
import requests
response = requests.get(
f"https://api.finseo.ai/v1/projects/{project_id}/fanouts",
headers={"Authorization": "Bearer YOUR_API_KEY"},
params={"timeframe": "30d", "limit": 20}
)
fanouts = response.json()["data"]["fanouts"]
for f in fanouts:
print(f"{f['query']} — {f['count']} occurrences across {f['promptCount']} prompts")
```
```javascript Node.js theme={"system"}
const res = await fetch(
`https://api.finseo.ai/v1/projects/${projectId}/fanouts?timeframe=30d`,
{ headers: { Authorization: "Bearer YOUR_API_KEY" } }
);
const { data } = await res.json();
data.fanouts.forEach(f => console.log(f.query, f.count));
```
```json 200 theme={"system"}
{
"data": {
"fanouts": [
{
"query": "best CRM for small business 2026",
"count": 47,
"promptCount": 12,
"models": ["chatgpt", "perplexity"],
"lastSeen": "2026-03-29T18:42:00Z",
"samplePrompt": "What CRM should I use for my startup?"
},
{
"query": "HubSpot vs Salesforce comparison",
"count": 32,
"promptCount": 8,
"models": ["chatgpt", "claude", "perplexity"],
"lastSeen": "2026-03-29T14:15:00Z",
"samplePrompt": "Compare HubSpot and Salesforce features"
}
],
"pagination": {
"page": 1,
"limit": 20,
"total": 156,
"hasMore": true
},
"meta": {
"totalResults": 420,
"totalPrompts": 42,
"timeframeDays": 30
}
}
}
```
# Automate a pitch
Source: https://docs.finseo.ai/api-reference/guides/automate-pitch
Create a pitch project, set its models, add prompts, read the results and convert a won pitch — the full agency flow in five API calls.
# Automate a pitch
Agencies run the same sequence for every prospect: create a pitch project, pick
the AI models, add the prompts, read the results a few days later and — if the
prospect signs — convert the pitch into a client project. Every step is
available via the REST API, with exactly the same limits and error codes as the
dashboard, so a pitch can be started from a CRM, a form or a script without
anyone opening the UI.
Pitch projects need an **Agency** account. They carry no project fee, are
capped at **50 prompts** and pause automatically when the pitch window
(1, 7 or 14 days) closes. The number of concurrent pitch projects is limited
per package.
## 1. Create the pitch project
`language` is required and drives the prompt language and country filter.
A new project starts with your account's default models.
```bash theme={"system"}
curl --request POST \
--url https://api.finseo.ai/v1/projects \
--header "Authorization: Bearer $FINSEO_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"name": "Prospect GmbH",
"websiteUrl": "https://www.prospect.example",
"language": "de",
"isPitch": true,
"pitchDurationDays": 7
}'
```
The response contains the `id` you need for every following call and the
current `models`. A `403` with `details.reason = "pitch_project_limit"` means
all pitch slots of your package are in use — convert or delete a pitch first.
## 2. Set the models
Prompts always run on the project's models, so set them **before** adding
prompts. This replaces the full set, the same way the Model Settings page does.
```bash theme={"system"}
curl --request PUT \
--url https://api.finseo.ai/v1/projects/{projectId} \
--header "Authorization: Bearer $FINSEO_API_KEY" \
--header 'Content-Type: application/json' \
--data '{"models": ["chatgpt", "perplexity", "ai_overview", "claude"]}'
```
A `403` with `details.reason = "agency_limit"` means the projected monthly
AI answers exceed the band included in your package (`details.nextPackage`
names the upgrade). On the top package the call succeeds and returns a
`meteredNotice` instead; the excess is billed as overage.
## 3. Add the prompts
Omit `models` to use the project's models. `language` defaults to the project
language. Each prompt is queued immediately (`enqueued: true`).
```python theme={"system"}
import requests
API = "https://api.finseo.ai/v1"
H = {"Authorization": "Bearer sk_live_xxxxxxxx"}
project_id = "67f8a1b2c3d4e5f60718293a4"
prompts = [
"Welche Agentur für AI-Sichtbarkeit ist in Deutschland empfehlenswert?",
"Beste Tools um die Sichtbarkeit einer Marke in ChatGPT zu messen",
"Prospect GmbH vs. Wettbewerber – wer ist besser?",
]
for text in prompts:
r = requests.post(f"{API}/projects/{project_id}/prompts", headers=H,
json={"prompt": text, "tags": ["pitch"]})
if r.status_code == 403:
print("stopped:", r.json()["error"]["details"]["reason"])
break
r.raise_for_status()
```
Possible `403` reasons: `pitch_prompt_limit` (50 prompts reached),
`pitch_expired`, `agency_limit`. Passing a model that is not enabled on the
project returns `400 model_not_enabled` — go back to step 2.
## 4. Read the results
Give the workers a few minutes for the first answers; a full pitch usually has
one run per day. Then read the KPIs, the competitor ranking and the per-prompt
breakdown for the pitch window:
```bash theme={"system"}
curl --url 'https://api.finseo.ai/v1/projects/{projectId}/metrics?timeframe=7d' \
--header "Authorization: Bearer $FINSEO_API_KEY"
curl --url 'https://api.finseo.ai/v1/projects/{projectId}/competitors?timeframe=7d' \
--header "Authorization: Bearer $FINSEO_API_KEY"
curl --url 'https://api.finseo.ai/v1/projects/{projectId}/prompts?timeframe=7d' \
--header "Authorization: Bearer $FINSEO_API_KEY"
```
`visibilityRate`, `mentionRate` and `citationRate` are explained in
[KPIs explained](/getting-started/kpis). Filter by a single engine with
`model=`, using one of the project's `models`.
## 5. Convert a won pitch
Turn the pitch into a billable client project: lifts the prompt cap, stops the
auto-pause and resumes anything the expiry paused.
```bash theme={"system"}
curl --request PUT \
--url https://api.finseo.ai/v1/projects/{projectId} \
--header "Authorization: Bearer $FINSEO_API_KEY" \
--header 'Content-Type: application/json' \
--data '{"convertFromPitch": true}'
```
A `403` with `details.reason = "agency_limit"` and `details.limit = "projects"`
means no client slot is free; with `details.limit = "answers"` the project's
prompts would exceed the included answer band at full-month pricing.
## Endpoints used
| Step | Endpoint |
| ------------ | ------------------------------------------------------------------------------------------------------------------------------------------------- |
| Create pitch | [POST /v1/projects](/api-reference/projects/create) |
| Set models | [PUT /v1/projects/\{projectId}](/api-reference/projects/update) |
| Add prompts | [POST /v1/projects/\{projectId}/prompts](/api-reference/prompts/add) |
| Read results | [GET /metrics](/api-reference/metrics/daily), [GET /competitors](/api-reference/competitors/ranking), [GET /prompts](/api-reference/prompts/list) |
| Convert | [PUT /v1/projects/\{projectId}](/api-reference/projects/update) with `convertFromPitch` |
# Project Metrics (Summary)
Source: https://docs.finseo.ai/api-reference/metrics/daily
GET /v1/projects/{projectId}/metrics
Returns aggregate AI visibility metrics for the current period vs the previous period of equal length. Use this for dashboards and KPIs for Finseo visibility across ChatGPT, Claude, Perplexity, and other tracked models.
The response carries the current period under `today` and the previous period under `yesterday` (legacy names — each block aggregates the whole period, `date` is the period's end date). All rates share the same denominator, `totalResponses` (see [KPIs explained](/getting-started/kpis)):
| Field | Meaning |
| ------------------------ | -------------------------------------------------------------------------------------------------------------------------------------------- |
| `responseVisibilityRate` | **Visibility** — % of answers where the brand is visible: named in the text OR own domain cited as a source (the dashboard "Visibility" KPI) |
| `mentionRate` | **Mention Rate** — % of answers naming the brand in the answer text |
| `citationRate` | **Citation Rate** — % of answers citing the own domain (or a configured domain alias) as a source |
| `mentions` / `cited` | Absolute counts behind Mention Rate and Citation Rate (answers, each counted once) |
| `visibilityRate` | Prompt coverage — % of tracked prompts with at least one visible answer (a different, usually higher number) |
| `visible` / `notVisible` | Number of prompts with / without a visible answer |
| `position` | Mention depth — how deep in the answer text the mention appears (0 = top), not a ranking |
An answer can count toward both `mentionRate` and `citationRate`, so `responseVisibilityRate ≤ mentionRate + citationRate`.
Project identifier.
Rolling window, e.g. `7d`, `30d`, `90d`. Ignored when `startDate`/`endDate` are set.
Custom range start (`YYYY-MM-DD`). Must be combined with `endDate`; overrides `timeframe`. The comparison period is the same number of days immediately before the custom range.
Custom range end (`YYYY-MM-DD`). Must be combined with `startDate`.
Restrict metrics to a single model.
Filter by prompt language.
JSON array or comma-separated tags to filter prompts.
Included for shared query parsing; metrics ignore pagination.
Included for shared query parsing; metrics ignore pagination.
```bash cURL theme={"system"}
curl --request GET \
--url 'https://api.finseo.ai/v1/projects/67a1c2d3e4f5061728394a5b/metrics?timeframe=30d' \
--header "Authorization: Bearer $FINSEO_API_KEY"
```
```python Python theme={"system"}
import requests
r = requests.get(
"https://api.finseo.ai/v1/projects/67a1c2d3e4f5061728394a5b/metrics",
headers={"Authorization": "Bearer sk_live_xxxxxxxx"},
params={"timeframe": "30d", "language": "en"},
)
metrics = r.json()["data"]
cur, chg = metrics["today"], metrics["changes"]
print(cur["responseVisibilityRate"], cur["mentionRate"], cur["citationRate"], chg["responseVisibilityRateChange"])
```
```json theme={"system"}
{
"data": {
"today": {
"date": "2026-09-08",
"visible": 28,
"notVisible": 14,
"mentions": 44,
"cited": 22,
"totalResponses": 84,
"position": 22.4,
"sentiment": 78,
"visibilityRate": 66.67,
"responseVisibilityRate": 59.52,
"mentionRate": 52.38,
"citationRate": 26.19
},
"yesterday": {
"date": "2026-08-09",
"visible": 22,
"notVisible": 20,
"mentions": 34,
"cited": 15,
"totalResponses": 76,
"position": 28.1,
"sentiment": 71,
"visibilityRate": 52.38,
"responseVisibilityRate": 50.0,
"mentionRate": 44.74,
"citationRate": 19.74
},
"changes": {
"visibleChange": 6,
"visibilityRateChange": 14.29,
"responseVisibilityRateChange": 9.52,
"mentionsChange": 10,
"citedChange": 7,
"mentionRateChange": 7.64,
"citationRateChange": 6.45,
"positionChange": -5.7,
"sentimentChange": 7
}
}
}
```
# Metrics Timeseries
Source: https://docs.finseo.ai/api-reference/metrics/timeseries
GET /v1/projects/{projectId}/metrics/timeseries
Returns daily AI visibility metrics for charting. Each row in `data.chartData` corresponds to a calendar day within the timeframe derived from `timeframe`, or within `startDate` / `endDate` when both are provided. Ideal for trend lines for Finseo across ChatGPT, Claude, and Perplexity.
Per-day fields (all counts are AI answers of that day; see [KPIs explained](/getting-started/kpis)):
| Field | Meaning |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `totalResults` | Analyzed AI answers on that day |
| `visible` / `notVisible` | Answers where the brand is visible (named in the text OR own domain cited) / not visible — `visible ÷ totalResults` is the dashboard **Visibility** |
| `mentions` | Answers naming the brand in the text — `mentions ÷ totalResults` is the **Mention Rate** |
| `cited` | Answers citing the own domain (or a domain alias) as a source — `cited ÷ totalResults` is the **Citation Rate**. `null` when the day was served from a rollup that does not carry citations |
| `mentionOrder` | Average ordinal position among the brands named (1 = named first; the dashboard **Position** KPI), `null` when the brand was not named |
| `position` | Mention depth — how deep in the answer text the mention appears (0 = top) |
| `sentiment` | Average sentiment score (0–100) across visible answers |
| `uniquePrompts` | Distinct prompts with at least one answer that day |
Project identifier.
Rolling window when `startDate` / `endDate` are not used.
ISO date `YYYY-MM-DD` (use with `endDate`).
ISO date `YYYY-MM-DD` (use with `startDate`).
Filter to one model.
Prompt language filter.
JSON array or comma-separated tags.
```bash cURL theme={"system"}
curl --request GET \
--url 'https://api.finseo.ai/v1/projects/67a1c2d3e4f5061728394a5b/metrics/timeseries?timeframe=14d' \
--header "Authorization: Bearer $FINSEO_API_KEY"
```
```python Python theme={"system"}
import requests
r = requests.get(
"https://api.finseo.ai/v1/projects/67a1c2d3e4f5061728394a5b/metrics/timeseries",
headers={"Authorization": "Bearer sk_live_xxxxxxxx"},
params={"timeframe": "14d", "model": "chatgpt"},
)
series = r.json()["data"]["chartData"]
last = series[-1]
print(last["date"], last["visible"] / last["totalResults"], last["mentions"], last["cited"])
```
```json theme={"system"}
{
"data": {
"chartData": [
{
"date": "2026-09-06",
"visible": 9,
"notVisible": 3,
"totalResults": 12,
"mentions": 8,
"cited": 4,
"position": 19.2,
"mentionOrder": 2.4,
"sentiment": 74,
"uniquePrompts": 12
},
{
"date": "2026-09-07",
"visible": 10,
"notVisible": 2,
"totalResults": 12,
"mentions": 9,
"cited": 5,
"position": 17.8,
"mentionOrder": 2.1,
"sentiment": 79,
"uniquePrompts": 12
},
{
"date": "2026-09-08",
"visible": 11,
"notVisible": 1,
"totalResults": 12,
"mentions": 10,
"cited": 5,
"position": 16.5,
"mentionOrder": 1.9,
"sentiment": 81,
"uniquePrompts": 12
}
],
"anchoredWindow": null
}
}
```
# Create Project
Source: https://docs.finseo.ai/api-reference/projects/create
POST /v1/projects
Creates a new project. Finseo will track AI visibility for the brand associated with this project across ChatGPT, Claude, Perplexity, and configured models.
A new project starts with your account's default AI models (returned as
`models`). Set the models for this project with
[Update Project](/api-reference/projects/update) before adding prompts —
prompts always run on the project's models.
The same limits apply as in the dashboard's create dialog: on Brand plans the
plan's project cap, on Agency packages the included client-project slots
(pitch projects are free slots) and the included pitch-project slots. A limit
violation returns `403` with `error.details.reason` = `agency_limit`
(`details.limit = "projects"`) or `pitch_project_limit`.
Display name (1–200 characters).
Language for the brand analysis and the generated prompts (case-insensitive).
One of: `en`, `de`, `fr`, `es`, `it`, `nl`, `pt`, `pl`, `sv`, `da`, `tr`, `ja`,
`no`, `fi`, `cs`, `ru`, `zh`, `zh-tw`, `ko`, `hi`, `ar`, `he`.
Canonical site URL; used to infer `domain` when omitted.
Root domain (e.g. `finseo.ai`). Optional if `websiteUrl` is provided.
Optional notes (max 500 characters).
Create a **pitch project**: no project fee, capped at 50 prompts, and
automatically paused once the pitch window closes. Ideal for sales agents
running one-off prospect analyses. Pitch project slots are limited per
agency package (e.g. 250 on Agency Starter, 500 on Agency Studio).
Pitch window in days: `1` (one-time run), `7` or `14`. Ignored unless
`isPitch` is `true`. Convert a won pitch to a full client project with
[Update Project](/api-reference/projects/update) and `convertFromPitch`.
```bash cURL theme={"system"}
curl --request POST \
--url https://api.finseo.ai/v1/projects \
--header "Authorization: Bearer $FINSEO_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"name": "Finseo Labs",
"websiteUrl": "https://labs.finseo.ai",
"language": "en",
"description": "Experimental prompts and benchmarks"
}'
```
```python Python theme={"system"}
import requests
payload = {
"name": "Finseo Labs",
"websiteUrl": "https://labs.finseo.ai",
"language": "en",
"description": "Experimental prompts and benchmarks",
}
r = requests.post(
"https://api.finseo.ai/v1/projects",
headers={"Authorization": "Bearer sk_live_xxxxxxxx"},
json=payload,
)
created = r.json()["data"]
print(created["id"])
```
```json theme={"system"}
{
"data": {
"id": "67f8a1b2c3d4e5f60718293a4",
"name": "Finseo Labs",
"websiteUrl": "https://labs.finseo.ai",
"domain": "labs.finseo.ai",
"description": "Experimental prompts and benchmarks",
"isDefault": false,
"tags": [],
"language": "en",
"models": ["chatgpt", "perplexity", "ai_overview"],
"createdAt": "2026-03-29T08:30:00.000Z",
"updatedAt": "2026-03-29T08:30:00.000Z"
}
}
```
```json Pitch project theme={"system"}
{
"data": {
"id": "67f8a1b2c3d4e5f60718293a4",
"name": "Prospect GmbH",
"websiteUrl": "https://prospect.example",
"domain": "prospect.example",
"description": "",
"isDefault": false,
"tags": [],
"isPitch": true,
"pitchDurationDays": 1,
"language": "de",
"models": ["chatgpt", "perplexity", "ai_overview"],
"createdAt": "2026-09-04T21:12:55.798Z",
"updatedAt": "2026-09-04T21:12:55.798Z"
}
}
```
# Get Project
Source: https://docs.finseo.ai/api-reference/projects/get
GET /v1/projects/{projectId}
Retrieves a single project by ID, including settings used for AI visibility tracking.
MongoDB-style project identifier.
```bash cURL theme={"system"}
curl --request GET \
--url https://api.finseo.ai/v1/projects/67a1c2d3e4f5061728394a5b \
--header "Authorization: Bearer $FINSEO_API_KEY"
```
```python Python theme={"system"}
import requests
project_id = "67a1c2d3e4f5061728394a5b"
r = requests.get(
f"https://api.finseo.ai/v1/projects/{project_id}",
headers={"Authorization": "Bearer sk_live_xxxxxxxx"},
)
print(r.json()["data"])
```
```json theme={"system"}
{
"data": {
"id": "67a1c2d3e4f5061728394a5b",
"name": "Finseo Marketing",
"domain": "finseo.ai",
"websiteUrl": "https://finseo.ai",
"description": "AI visibility tracking for Finseo",
"isDefault": true,
"tags": ["product", "b2b"],
"language": "en",
"isPitch": false,
"models": ["chatgpt", "perplexity", "ai_overview"],
"settings": {
"brandAliases": ["Finseo", "Fin SEO"],
"defaultLanguage": "en"
},
"createdAt": "2025-11-12T10:15:00.000Z",
"updatedAt": "2026-03-28T14:22:00.000Z"
}
}
```
# List Projects
Source: https://docs.finseo.ai/api-reference/projects/list
GET /v1/projects
Returns a list of projects your API key can access. Projects represent tracked brands or domains in Finseo for AI visibility across ChatGPT, Claude, Perplexity, and other models.
Every project includes `isPitch`. Pitch projects additionally carry
`pitchDurationDays` (1, 7 or 14) and `pitchExpiredAt` (`null` while the pitch
window is still open), so an agent can see how long a pitch keeps running
without guessing.
Every project also returns `language` (the prompt language set at creation,
`null` on older projects) and `models` — the AI models its prompts run on,
i.e. the dashboard's Model Settings. Use these values for the `model` filter
on the metrics endpoints, and change them with
[Update Project](/api-reference/projects/update).
```bash cURL theme={"system"}
curl --request GET \
--url https://api.finseo.ai/v1/projects \
--header "Authorization: Bearer $FINSEO_API_KEY"
```
```python Python theme={"system"}
import requests
response = requests.get(
"https://api.finseo.ai/v1/projects",
headers={"Authorization": "Bearer sk_live_xxxxxxxx"},
)
projects = response.json()["data"]
for p in projects:
print(p["name"], p["id"])
```
```json theme={"system"}
{
"data": [
{
"id": "67a1c2d3e4f5061728394a5b",
"name": "Finseo Marketing",
"domain": "finseo.ai",
"websiteUrl": "https://finseo.ai",
"description": "AI visibility tracking for modern brands",
"isDefault": true,
"tags": ["product", "b2b"],
"language": "en",
"models": ["chatgpt", "perplexity", "ai_overview"],
"isPitch": false,
"createdAt": "2025-11-12T10:15:00.000Z",
"updatedAt": "2026-03-28T14:22:00.000Z"
},
{
"id": "67b2d3e4f5061728394a5c",
"name": "Acme Corp (Pitch)",
"domain": "acme.com",
"websiteUrl": "https://www.acme.com",
"description": "",
"isDefault": false,
"tags": [],
"language": "de",
"models": ["chatgpt", "perplexity", "ai_overview", "claude"],
"isPitch": true,
"pitchDurationDays": 7,
"pitchExpiredAt": null,
"createdAt": "2026-01-08T09:00:00.000Z",
"updatedAt": "2026-03-15T11:45:00.000Z"
}
]
}
```
# Update Project
Source: https://docs.finseo.ai/api-reference/projects/update
PUT /v1/projects/{projectId}
Updates an existing project. Send only the fields you want to change.
Project identifier.
New display name (1–200 characters).
Updated canonical URL.
Updated root domain.
Updated description (max 500 characters).
Set to `true` to convert a pitch project into a full client project — for
example after winning the prospect. The conversion checks that a client
project slot is free and that the answer budget of your plan covers the
project's prompts, then reactivates any paused prompts. Fails if the
project is not a pitch project.
AI models the project's prompts run on — the API counterpart of the
dashboard's **Model Settings**. Replaces the full set and re-syncs every
prompt of the project (`syncedPromptCount` in the response); the next
scheduled run uses the new set. Allowed values: `chatgpt`, `perplexity`,
`ai_overview`, `google_ai_mode`, `copilot`, `claude`, `gemini`, `grok`,
`mistral`, `deepseek`.
The same limits apply as in the dashboard: the model cap of your plan
(3 on Brand plans unless raised), the prompt budget on Brand plans, and the
included AI-answer band on Agency packages. On the top Agency package the
call succeeds and returns a `meteredNotice` when the projection exceeds the
included answers — the excess is billed as overage, exactly as in the UI.
## Errors
Limit violations return `403` with `error.code = "FORBIDDEN"` and a
machine-readable `error.details.reason`:
| `details.reason` | Meaning |
| ------------------------ | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `model_limit` | More models than your plan allows (`details.limit`). |
| `model_not_available` | Engine not available on your plan (`details.models`). |
| `prompt_budget_exceeded` | Brand plan: the new model set would exceed the prompt budget (`promptLimit`, `slotsUsed`, `projectedSlots`). |
| `agency_limit` | Agency: projected monthly answers exceed the included band and a higher package exists (`package`, `nextPackage`, `includedResults`, `projectedMonthlyAnswers`) — or, for `convertFromPitch`, no client slot is free (`details.limit = "projects"`). |
```bash cURL theme={"system"}
curl --request PUT \
--url https://api.finseo.ai/v1/projects/67a1c2d3e4f5061728394a5b \
--header "Authorization: Bearer $FINSEO_API_KEY" \
--header 'Content-Type: application/json' \
--data '{"name": "Finseo — Growth", "description": "Primary Finseo GTM project"}'
```
```bash Set models theme={"system"}
curl --request PUT \
--url https://api.finseo.ai/v1/projects/67a1c2d3e4f5061728394a5b \
--header "Authorization: Bearer $FINSEO_API_KEY" \
--header 'Content-Type: application/json' \
--data '{"models": ["chatgpt", "perplexity", "ai_overview", "claude"]}'
```
```python Python theme={"system"}
import requests
project_id = "67a1c2d3e4f5061728394a5b"
r = requests.put(
f"https://api.finseo.ai/v1/projects/{project_id}",
headers={"Authorization": "Bearer sk_live_xxxxxxxx"},
json={"models": ["chatgpt", "perplexity", "ai_overview", "claude"]},
)
if r.status_code == 403:
print("blocked:", r.json()["error"]["details"]["reason"])
else:
print(r.json()["data"]["models"])
```
```json theme={"system"}
{
"data": {
"id": "67a1c2d3e4f5061728394a5b",
"updated": true
}
}
```
```json Models updated theme={"system"}
{
"data": {
"id": "67a1c2d3e4f5061728394a5b",
"updated": true,
"models": ["chatgpt", "perplexity", "ai_overview", "claude"],
"syncedPromptCount": 15
}
}
```
```json 403 agency_limit theme={"system"}
{
"error": {
"code": "FORBIDDEN",
"message": "Running 4 models would need 58,400 AI answers per month, above the 40,000 included in your solo package.",
"details": {
"reason": "agency_limit",
"package": "solo",
"nextPackage": "starter",
"includedResults": 40000,
"projectedMonthlyAnswers": 58400
}
}
}
```
```json Converted from pitch theme={"system"}
{
"data": {
"id": "67a1c2d3e4f5061728394a5b",
"updated": true,
"convertedFromPitch": true
}
}
```
# Create Prompt
Source: https://docs.finseo.ai/api-reference/prompts/add
POST /v1/projects/{projectId}/prompts
Adds a new tracking prompt to a project. Finseo will run this prompt on the project's AI models and record visibility for your brand vs competitors across ChatGPT, Claude, Perplexity and the other enabled models.
The prompt is queued for processing immediately (`enqueued: true` in the response); first answers typically arrive within a few minutes. The prompt inherits the project's domain, brand name, synonyms, domain aliases and tracking frequency — the project therefore needs a `websiteUrl`, otherwise the request is rejected with `400`.
Project identifier.
Prompt text (1–500 characters).
Optional. Defaults to the project's enabled models (the dashboard's **Model
Settings**, returned as `models` by [Get Project](/api-reference/projects/get)).
When given, it must be a **subset** of those — a prompt cannot run on a model
the project has not enabled, otherwise the dashboard filters and the prompt
data would disagree. Enable models for the project first via
[Update Project](/api-reference/projects/update). A model outside the
enabled set is rejected with `400` and a message starting with
`model_not_enabled`.
Language / market code for the prompt (e.g. `de`, `en`). Defaults to the
project's `language`. The value is normalised to the dashboard's spelling
(`de` → `DE`) so the country filter matches.
Optional string tags for filtering in analytics.
Pitch projects (`isPitch: true`) are limited to **50 prompts**. Adding
prompts to an expired pitch project is rejected — convert it to a client
project first via [Update Project](/api-reference/projects/update).
## Errors
The same limits apply as when adding a prompt in the dashboard. Violations
return `403` with `error.code = "FORBIDDEN"` and `error.details.reason`:
| `details.reason` | Meaning |
| ------------------------ | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `prompt_limit` | Prompt cap of your plan reached (`promptsUsed`, `promptLimit`). |
| `prompt_budget_exceeded` | Brand plan: this prompt on these models would exceed the prompt budget (`promptLimit`, `slotsUsed`, `projectedSlots`). |
| `agency_limit` | Agency: projected monthly answers exceed the included band and a higher package exists (`package`, `nextPackage`, `includedResults`, `projectedMonthlyAnswers`). The top package is never blocked; the excess is billed as overage. |
| `pitch_prompt_limit` | Pitch project already has 50 prompts (`current`, `limit`). |
| `pitch_expired` | The pitch window has closed; convert the project first. |
```bash cURL theme={"system"}
curl --request POST \
--url https://api.finseo.ai/v1/projects/67a1c2d3e4f5061728394a5b/prompts \
--header "Authorization: Bearer $FINSEO_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"prompt": "How does Finseo compare to traditional SEO suites?",
"language": "en",
"tags": ["comparison", "Finseo"]
}'
```
```python Python theme={"system"}
import requests
payload = {
"prompt": "How does Finseo compare to traditional SEO suites?",
"language": "en",
"tags": ["comparison", "Finseo"],
}
r = requests.post(
"https://api.finseo.ai/v1/projects/67a1c2d3e4f5061728394a5b/prompts",
headers={"Authorization": "Bearer sk_live_xxxxxxxx"},
json=payload,
)
print(r.json()["data"])
```
```json theme={"system"}
{
"data": {
"id": "b2c3d4e5-f6a7-8901-bcde-f12345678901",
"prompt": "How does Finseo compare to traditional SEO suites?",
"domain": "https://www.finseo.ai",
"brand_name": "Finseo",
"language": "EN",
"models": ["chatgpt", "perplexity", "ai_overview"],
"tags": ["comparison", "Finseo"],
"project_id": "67a1c2d3e4f5061728394a5b",
"active": true,
"processing_complete": false,
"created_at": "2026-09-10T09:41:12.481Z",
"enqueued": true
}
}
```
```json 400 model_not_enabled theme={"system"}
{
"error": {
"code": "VALIDATION_ERROR",
"message": "model_not_enabled: mistral is not enabled for this project (enabled: chatgpt, perplexity, ai_overview). Enable it via PUT /v1/projects/{projectId} with \"models\", or omit \"models\" to use the project settings."
}
}
```
# List Prompts
Source: https://docs.finseo.ai/api-reference/prompts/list
GET /v1/projects/{projectId}/prompts
Lists tracked prompts for a project with visibility, mention counts, citations, and sentiment for the selected timeframe. Finseo evaluates these prompts against ChatGPT, Claude, Perplexity, and other models.
Per prompt, all counts refer to the AI answers of the selected timeframe (`resultCount`; see [KPIs explained](/getting-started/kpis)):
* `isVisible` — the brand was visible in at least one answer: named in the answer text OR the own domain cited as a source
* `totalMentions` / `mentionRate` — answers naming the brand in the text, and that count as a % of `resultCount` (**Mention Rate**)
* `ownDomainCitations` / `citationRate` — answers citing the own domain (or a configured domain alias) as a source, and that count as a % of `resultCount` (**Citation Rate**)
`avgPosition` in the response is the **Mention Depth**: how deep in the answer text the brand mention appears (0% = very top). It is not a ranking position — for the ordinal Position KPI see the [competitors endpoint](/api-reference/competitors/ranking) (`avgMentionOrder`) and [KPIs explained](/getting-started/kpis).
Project identifier.
Rolling window length, e.g. `7d`, `30d`, `90d`. This endpoint only supports relative windows — custom `startDate`/`endDate` ranges are not available here and are rejected with a `400`.
Filter results to a single model (e.g. `chatgpt`).
ISO language code filter (e.g. `en`, `de`).
JSON array string or comma-separated tag names to filter prompts.
Case-insensitive substring match on prompt text.
Page number (1-based).
Page size (1–500).
```bash cURL theme={"system"}
curl --request GET \
--url 'https://api.finseo.ai/v1/projects/67a1c2d3e4f5061728394a5b/prompts?timeframe=30d&limit=10&page=1' \
--header "Authorization: Bearer $FINSEO_API_KEY"
```
```python Python theme={"system"}
import requests
params = {"timeframe": "30d", "limit": 10, "page": 1, "search": "Finseo"}
r = requests.get(
"https://api.finseo.ai/v1/projects/67a1c2d3e4f5061728394a5b/prompts",
headers={"Authorization": "Bearer sk_live_xxxxxxxx"},
params=params,
)
body = r.json()["data"]
first = body["prompts"][0]
print(body["totalCount"], first["prompt"], first["mentionRate"], first["citationRate"])
```
```json theme={"system"}
{
"data": {
"prompts": [
{
"id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"prompt": "What are the best AI SEO tools including Finseo?",
"domain": "finseo.ai",
"brandName": "finseo",
"language": "en",
"tags": ["branded", "comparison"],
"models": ["chatgpt", "claude", "perplexity"],
"createdAt": "2026-02-10T12:00:00.000Z",
"updatedAt": "2026-09-01T08:00:00.000Z",
"lastCheckedAt": "2026-09-08T06:12:00.000Z",
"isVisible": true,
"totalMentions": 14,
"mentionRate": 46.7,
"avgPosition": 18.2,
"sentimentScore": 76,
"resultCount": 30,
"competitorCount": 6,
"sourceCount": 22,
"ownDomainCitations": 9,
"ownDomainCitationsChange": 3,
"citationRate": 30.0,
"mentionsChange": 2,
"sentimentChange": 4,
"positionChange": -1.5,
"visibilityChange": 6,
"topCompetitors": [
{ "brandName": "Competitor A", "domain": "competitor-a.com", "mentions": 11, "isUserBrand": false }
]
}
],
"totalCount": 48,
"currentPage": 1,
"totalPages": 5,
"hasMore": true
}
}
```
# List Sources
Source: https://docs.finseo.ai/api-reference/sources/ranking
GET /v1/projects/{projectId}/sources
Lists domains and URLs cited in AI answers for your tracked prompts—useful for understanding which sources drive visibility for Finseo-related queries across ChatGPT, Claude, and Perplexity.
Project identifier.
Rolling window for citations. Ignored when `startDate`/`endDate` are set.
Custom range start (`YYYY-MM-DD`). Must be combined with `endDate`; overrides `timeframe`.
Custom range end (`YYYY-MM-DD`). Must be combined with `startDate`.
Filter by answer model.
Filter prompts by language.
JSON array or comma-separated prompt tags.
Match domain or title substring.
One of `citations`, `domain`, `type`.
`asc` or `desc`.
Page number.
Page size (1–500).
```bash cURL theme={"system"}
curl --request GET \
--url 'https://api.finseo.ai/v1/projects/67a1c2d3e4f5061728394a5b/sources?timeframe=30d&sortBy=citations' \
--header "Authorization: Bearer $FINSEO_API_KEY"
```
```python Python theme={"system"}
import requests
r = requests.get(
"https://api.finseo.ai/v1/projects/67a1c2d3e4f5061728394a5b/sources",
headers={"Authorization": "Bearer sk_live_xxxxxxxx"},
params={"timeframe": "30d", "search": "finseo", "limit": 25},
)
print(r.json()["data"]["sources"][0]["domain"])
```
```json theme={"system"}
{
"data": {
"sources": [
{
"id": "e9f0a1b2-c3d4-4657-ef01-890123456cde",
"url": "https://finseo.ai/blog/ai-visibility",
"domain": "finseo.ai",
"title": "AI Visibility Benchmarks — Finseo",
"sourceType": "website",
"urlType": "content",
"citationCount": 89,
"promptCount": 34,
"averagePosition": 2.1
},
{
"id": "f0a1b2c3-d4e5-4768-f012-901234567def",
"url": "https://www.reddit.com/r/SEO/comments/example",
"domain": "reddit.com",
"title": "Discussion on AI SEO tools",
"sourceType": "community",
"urlType": "ugc",
"citationCount": 41,
"promptCount": 18,
"averagePosition": 4.6
}
],
"pagination": {
"page": 1,
"limit": 25,
"total": 120,
"hasMore": true
}
}
}
```
# Apply Tag to Prompts
Source: https://docs.finseo.ai/api-reference/tags/create
POST /v1/projects/{projectId}/tags
Adds a tag to one or more prompts. The tag is merged with existing prompt tags so you can organize Finseo tracking cohorts without replacing other labels.
Project identifier.
Tag name (1–100 characters).
Non-empty list of prompt UUIDs to update.
```bash cURL theme={"system"}
curl --request POST \
--url https://api.finseo.ai/v1/projects/67a1c2d3e4f5061728394a5b/tags \
--header "Authorization: Bearer $FINSEO_API_KEY" \
--header 'Content-Type: application/json' \
--data '{
"name": "Q1-2026",
"promptIds": ["a1b2c3d4-e5f6-7890-abcd-ef1234567890", "b2c3d4e5-f6a7-8901-bcde-f12345678901"]
}'
```
```python Python theme={"system"}
import requests
payload = {
"name": "Q1-2026",
"promptIds": [
"a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"b2c3d4e5-f6a7-8901-bcde-f12345678901",
],
}
r = requests.post(
"https://api.finseo.ai/v1/projects/67a1c2d3e4f5061728394a5b/tags",
headers={"Authorization": "Bearer sk_live_xxxxxxxx"},
json=payload,
)
print(r.json()["data"])
```
```json theme={"system"}
{
"data": {
"tag": "Q1-2026",
"appliedTo": 2
}
}
```
# List Tags
Source: https://docs.finseo.ai/api-reference/tags/list
GET /v1/projects/{projectId}/tags
Returns all unique tag names used on active prompts in the project. Tags help segment Finseo analytics (e.g. branded vs unbranded, or campaign labels).
Project identifier.
```bash cURL theme={"system"}
curl --request GET \
--url https://api.finseo.ai/v1/projects/67a1c2d3e4f5061728394a5b/tags \
--header "Authorization: Bearer $FINSEO_API_KEY"
```
```python Python theme={"system"}
import requests
r = requests.get(
"https://api.finseo.ai/v1/projects/67a1c2d3e4f5061728394a5b/tags",
headers={"Authorization": "Bearer sk_live_xxxxxxxx"},
)
tags = r.json()["data"]
print(tags)
```
```json theme={"system"}
{
"data": [
"Finseo",
"branded",
"comparison",
"enterprise",
"product"
]
}
```
# Get Task
Source: https://docs.finseo.ai/api-reference/tasks/get
GET /v1/projects/{projectId}/tasks/{taskId}
Read one optimization task in full — description, step-by-step action plan, the evidence that triggered it, and the structured content plan for content tasks.
Returns the complete task: the full description, a step-by-step action plan, the evidence (data points and affected prompts or sources) that triggered the task, and — for content tasks — a structured `contentPlan` describing the target page, template and prompts the content should cover.
Get the `taskId` from [List Tasks](/api-reference/tasks/list) (field `id`).
The project ID
The task ID (UUID) from List Tasks
```bash cURL theme={"system"}
curl --request GET \
--url 'https://api.finseo.ai/v1/projects/proj_abc123/tasks/05ba7f64-9c1e-4f2a-8d3b-1a2b3c4d5e6f' \
--header "Authorization: Bearer $FINSEO_API_KEY"
```
```python Python theme={"system"}
import requests
response = requests.get(
f"https://api.finseo.ai/v1/projects/{project_id}/tasks/{task_id}",
headers={"Authorization": "Bearer YOUR_API_KEY"}
)
task = response.json()["data"]
print(task["title"])
for i, step in enumerate(task["steps"], 1):
print(f"{i}. {step}")
```
```javascript Node.js theme={"system"}
const res = await fetch(
`https://api.finseo.ai/v1/projects/${projectId}/tasks/${taskId}`,
{ headers: { Authorization: "Bearer YOUR_API_KEY" } }
);
const { data: task } = await res.json();
console.log(task.title, task.steps);
```
```json 200 theme={"system"}
{
"data": {
"id": "05ba7f64-9c1e-4f2a-8d3b-1a2b3c4d5e6f",
"title": "Redirect the broken marketplace URL",
"category": "technical",
"status": "open",
"impact": 10,
"effort": 2,
"priorityScore": 96,
"description": "The URL https://example.com/marketplace/197275 currently returns HTTP 404 although it appears in your AI traffic data…",
"steps": [
"Verify the URL returns 404 in your CMS",
"Identify the best matching live page",
"Set up a 301 redirect",
"Re-run the crawl check"
],
"evidence": {
"summary": "URL returns 404 but received 23 AI-referred visits in the last 30 days",
"metrics": [
{ "label": "HTTP status", "value": "404" },
{ "label": "AI-referred visits (30d)", "value": "23" }
],
"items": [],
"deepLink": "/bot-traffic"
},
"contentPlan": null,
"assigneeEmail": null,
"exports": [],
"autoResolvable": true,
"autoResolved": false,
"resolvedAt": null,
"lastSeenAt": "2026-08-12T15:20:00Z",
"createdAt": "2026-08-12T15:20:00Z",
"updatedAt": "2026-08-12T15:20:00Z"
}
}
```
```json 404 theme={"system"}
{
"error": {
"code": "NOT_FOUND",
"message": "Task not found"
}
}
```
# List Tasks
Source: https://docs.finseo.ai/api-reference/tasks/list
GET /v1/projects/{projectId}/tasks
List the AI-generated optimization tasks for a project — concrete, prioritized to-dos derived from your visibility data, sorted by priority score.
Optimization tasks are generated automatically from your project's AI visibility data — for example fixing crawl errors AI bots hit, answering high-potential community threads, closing competitor gaps, or reworking weak content. This endpoint returns the same tasks as the Tasks page in the Finseo dashboard.
Rows are compact and sorted by `priorityScore` (impact weighted against effort — higher means do it first). Use [Get Task](/api-reference/tasks/get) with a task `id` for the full description, step-by-step plan and evidence.
The Tasks module is currently in beta. Tasks are read-only via the API — status changes happen in the dashboard.
The project ID
Comma-separated statuses to include — `open`, `in_progress`, `done`, `dismissed`, or `all`
Filter by category — `technical`, `visibility`, `content`, `offsite`, `reputation`, `competitor`, or `setup`
Only return tasks with at least this impact score (1–10)
Page number
Results per page (max 200)
```bash cURL theme={"system"}
curl --request GET \
--url 'https://api.finseo.ai/v1/projects/proj_abc123/tasks?status=open&limit=10' \
--header "Authorization: Bearer $FINSEO_API_KEY"
```
```python Python theme={"system"}
import requests
response = requests.get(
f"https://api.finseo.ai/v1/projects/{project_id}/tasks",
headers={"Authorization": "Bearer YOUR_API_KEY"},
params={"status": "open", "limit": 10}
)
tasks = response.json()["data"]["tasks"]
for t in tasks:
print(f"[{t['priorityScore']}] {t['category']}: {t['title']}")
```
```javascript Node.js theme={"system"}
const res = await fetch(
`https://api.finseo.ai/v1/projects/${projectId}/tasks?status=open`,
{ headers: { Authorization: "Bearer YOUR_API_KEY" } }
);
const { data } = await res.json();
data.tasks.forEach(t => console.log(t.priorityScore, t.title));
```
```json 200 theme={"system"}
{
"data": {
"counts": { "open": 33, "in_progress": 2, "done": 5, "dismissed": 1 },
"total": 33,
"page": 1,
"limit": 10,
"hasMore": true,
"tasks": [
{
"id": "05ba7f64-9c1e-4f2a-8d3b-1a2b3c4d5e6f",
"title": "Redirect the broken marketplace URL",
"category": "technical",
"status": "open",
"impact": 10,
"effort": 2,
"priorityScore": 96,
"autoResolved": false,
"assigneeEmail": null,
"createdAt": "2026-08-12T15:20:00Z",
"updatedAt": "2026-08-12T15:20:00Z"
}
]
}
}
```
# Set Up AI Search Attribution: Forms, CRMs & Orders
Source: https://docs.finseo.ai/attribution
Connect leads, orders, and revenue to the channels customers actually found you through — including AI search.
# Attribution
Attribution connects your AI visibility data to real leads and revenue. Instead of only seeing whether your brand appears in AI answers, you can see whether customers actually say they found you through ChatGPT, Perplexity, Claude, Google, ads, referrals, or other channels — and how much revenue each channel drives.
Finseo attribution works with two kinds of data that are merged automatically:
* **Responses** — a customer's answer to "How did you hear about us?", from the Finseo survey popup, your own forms, a survey tool, or your CRM.
* **Conversions** — purchases and leads with a transaction ID and value, from your existing tracking (Google/Meta), Stripe, your shop system, or a webhook.
When a response and a conversion share the same order ID or email, they merge into one attributed data point: "this €1,234 order came from ChatGPT."
## Guided setup
The fastest way to set up attribution is the built-in wizard: open **Attribution** in your dashboard and click **Set up attribution**. It asks what you want to track (purchases, leads, or both), which system you run, and whether you already have tracking or a post-purchase survey — then it recommends exactly one install path with copy-paste snippets and verifies live that the first event arrives.
The recommended paths, depending on your setup:
One script tag. Survey popup plus automatic purchase capture from your existing Google/Meta tracking.
One Stripe webhook event. Amounts, trials, and renewals are classified automatically.
A Custom Pixel that reports every completed checkout — theme scripts can't run on Shopify's checkout, the pixel can.
A native order webhook, including WooCommerce's built-in Order Attribution origin.
A Flow Builder webhook on "Order placed".
HubSpot, Pipedrive, Calendly, form tools, or your own backend.
## The Finseo Snippet
The snippet is a single script tag served per project:
```html theme={"system"}
```
Paste it before `` on every page (or add it via Google Tag Manager as a Custom HTML tag). It does three things:
### 1. Captures answers from your existing forms
If your forms already ask "How did you hear about us?" (also detected in German: "Wie bist du auf uns aufmerksam geworden?"), the snippet captures that answer on submit — the popup then never shows. Emails and names from the same form are attached as merge keys so the answer can later be linked to a deal or order.
### 2. Shows the survey popup
If no form on the page asks the question, the snippet shows a small popup with your configured question and answer options. You control everything in **Attribution → Survey settings**:
* **Question and channels** — default channels include AI Search, Google/Bing, Social Media, Online Ads, Referral, Content, and Other (with free text). You can also use detailed AI channels (ChatGPT, Perplexity, Claude, Gemini, Copilot).
* **Trigger** — on page load, after form submit, after a detected purchase, or manual via JavaScript.
* **Style** — accent color, position, corner radius, font (system or inherit from your site), and optional answer shuffling to avoid position bias ("Other" always stays last).
Each visitor is asked only once (stored in `localStorage`).
### 3. Piggybacks on your existing conversion tracking
If Google Analytics / Google Ads (`dataLayer` / `gtag`) or the Meta Pixel (`fbq`) is installed, the snippet passively listens for conversion events and reports them to Finseo — no duplicate tracking setup:
| Source | Events captured |
| -------------------- | --------------------------------------------------------------------------------- |
| `dataLayer` / `gtag` | `purchase` (incl. GA4 and Universal Analytics ecommerce formats), `generate_lead` |
| Meta Pixel (`fbq`) | `Purchase`, `Lead` |
The snippet reads transaction ID, value, currency, and items from the event, deduplicates per transaction ID (thank-you-page reloads are not counted twice), and also scans events that fired before it loaded. Visitor-facing behavior is never altered.
### JavaScript API
For manual control, the snippet exposes a small API:
```js theme={"system"}
// Show the survey popup programmatically (e.g. after signup)
window.finseoAttribution.show();
// Report a conversion from your own code
window.finseoAttribution.trackConversion({
transactionId: "ORDER-12345",
value: 1234.56,
currency: "EUR",
email: "kunde@example.com" // optional merge key
});
```
## How responses and conversions merge
Conversions and survey answers usually arrive separately — a customer answers the popup while browsing, and the order comes in later via Stripe or your shop webhook. Finseo merges them automatically:
* **Merge keys**: transaction ID (`respondentExternalId` ↔ `transactionId`) or email. A transaction-ID match always wins over an email match.
* **Windows**: a new conversion looks back **90 days** for a survey answer (SaaS trials often convert weeks after signup). A new survey answer only looks back **48 hours** for an unmatched conversion, so a fresh answer is never linked to an old, unrelated order.
* **Deal values**: if the answer has no deal value, the merged conversion's amount fills it in — revenue is never counted twice.
* **Conversion types**: Stripe checkouts with a \$0 total are stored as **trials**, recurring invoices as **renewals**. Only regular purchases count as new customers awaiting attribution.
* **Unattributed revenue**: conversions that never got a survey answer are shown as their own KPI, so you always see how much revenue is still unexplained.
Whatever sends the conversion (Stripe, Shopify Pixel, webhook), always include the customer email when available — it is the most reliable merge key for leads that answer the survey before buying.
## Privacy by default
Customer emails are **SHA-256-hashed at ingestion**. Finseo never stores plaintext addresses — only the hash (used to merge orders with survey answers) and a masked preview like `j***@company.com` for the dashboard.
## Import answers from survey tools
Already running a post-purchase survey? Keep it — Finseo imports its answers instead of showing a second popup:
Via Shopify Flow
Via native webhook
Via native webhook
Via Zapier/Make
Native support
Native support
## Send data with a webhook
Your project webhook endpoint has this shape:
```text theme={"system"}
https://app.finseo.ai/api/attribution/webhook/PROJECT_ID?token=WEBHOOK_TOKEN
```
You can find or regenerate the webhook token in the Attribution settings for the project. Treat the URL like a secret — the token authenticates every request.
Send `POST` requests with `Content-Type: application/json`. Form-encoded and multipart form submissions are also accepted for form tools that cannot send raw JSON.
```bash theme={"system"}
curl --request POST \
--url "https://app.finseo.ai/api/attribution/webhook/PROJECT_ID?token=wh_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
--header "Content-Type: application/json" \
--data '{
"channelId": "AI Search",
"respondentEmail": "kunde@example.com",
"respondentName": "Max Mustermann",
"respondentExternalId": "BESTELLUNG-12345",
"dealValue": 1234.56,
"dealCurrency": "EUR",
"metadata": {
"produkt": "Produkt XY",
"sku": "ABC-123",
"menge": 2
}
}'
```
Successful webhook responses look like this:
```json theme={"system"}
{
"success": true,
"id": "response-id",
"source": "raw"
}
```
### Order-only payloads become conversions
If a payload carries order data (transaction ID + amount) but no attribution answer — a Stripe event, a WooCommerce order, or a custom order webhook — Finseo stores it as a **conversion** instead of rejecting it. The response then looks like this:
```json theme={"system"}
{
"success": true,
"type": "conversion",
"id": "conversion-id",
"matched": true
}
```
`matched: true` means the conversion was immediately merged with an earlier survey answer.
## Field reference
| Field | Required | Description |
| ---------------------- | -------- | ----------------------------------------------------------------------------------------------------------------------- |
| `channelId` | Yes | The source selected by the customer, for example `AI Search`, `ChatGPT`, `Google`, `Referral`, or `Paid Ads`. |
| `channelLabel` | No | Human-readable label if you want it to differ from `channelId`. |
| `channelCategory` | No | Optional category such as `ai_search`, `organic_search`, `paid`, `social`, `referral`, `content`, `direct`, or `other`. |
| `respondentEmail` | No | Customer or lead email. Also accepted as `email` in raw webhooks. Hashed at ingestion. |
| `respondentName` | No | Customer or lead name. Also accepted as `name` in raw webhooks. |
| `respondentExternalId` | No | ID from your CRM, order system, checkout, or data warehouse — the strongest merge key for conversions. |
| `dealValue` | No | Numeric revenue or pipeline value. |
| `dealCurrency` | No | Currency code such as `EUR`, `USD`, or `GBP`. Send the currency as paid. |
| `freetextResponse` | No | Original text answer if the customer used a free-text field. |
| `formId` | No | Form, survey, or source identifier. |
| `pageUrl` | No | Page where the form or checkout happened. |
| `metadata` | No | Extra key-value data such as product, SKU, country, plan, or quantity. |
Finseo normalizes channel text into categories. For example, answers containing `chatgpt`, `openai`, `claude`, `perplexity`, `gemini`, `copilot`, or `ai search` are categorized as `ai_search`.
## Map incoming fields
Many tools send payloads with their own names, such as `LeadSource`, `how_did_you_find_us`, `q3_howDid`, or nested Typeform answers. Finseo can map these fields in Attribution workflows.
1. Open **Attribution**.
2. Go to **Workflows**.
3. Send one test webhook from your source system.
4. Open the created workflow.
5. Map the incoming fields to attribution, email, name, deal value, currency, form ID, or rules.
6. Save the mapping.
After mapping, future webhooks with the same structure are parsed automatically. When a payload cannot be parsed at all, Finseo creates the workflow for you and suggests a field mapping using AI — you only need to confirm it.
```json theme={"system"}
{
"attribution": "lead.source",
"email": "lead.email",
"name": "lead.full_name",
"dealValue": "order.total",
"dealCurrency": "order.currency",
"formId": "form.id"
}
```
You can also use rules when a source field needs to be translated. For example, if `utm_source` contains `chatgpt`, map it to `AI Search`.
## Supported source formats
Finseo auto-detects several common sources:
* **HubSpot**: legacy contact webhook payloads with `properties`, or custom JSON bodies from Operations Hub.
* **Typeform**: `form_response.answers`, including choice, choices, text, and email fields.
* **Tally**: `data.fields` payloads.
* **Salesforce**: JSON from Flow HTTP Callout, for example `LeadSource`, `Email`, `Name`, `Amount`, and `CurrencyIsoCode`.
* **Jotform**: multipart/form-data with `rawRequest` or fields like `q3_howDid`, `formID`, and `submissionID`.
* **Stripe**: event payloads (`checkout.session.completed`, `invoice.paid`, …) — stored as conversions with automatic cent conversion and trial/renewal classification.
* **WooCommerce**: order webhooks, including Order Attribution meta as the marketing origin.
* **Shopware**: Flow Builder order payloads with `orderNumber`, `amountTotal`, and customer email.
* **Raw JSON**: direct payloads with fields like `channelId`, `respondentEmail`, `dealValue`, and `metadata`.
## Examples
```json CRM lead theme={"system"}
{
"channelId": "ChatGPT",
"respondentEmail": "jane@company.com",
"respondentName": "Jane Smith",
"respondentExternalId": "lead_98421",
"dealValue": 12000,
"dealCurrency": "EUR",
"metadata": {
"country": "DE",
"plan": "Enterprise"
}
}
```
```json Ecommerce order theme={"system"}
{
"channelId": "Perplexity",
"respondentEmail": "kunde@example.com",
"respondentExternalId": "ORDER-12345",
"dealValue": 1234.56,
"dealCurrency": "EUR",
"metadata": {
"produkt": "Produkt XY",
"sku": "ABC-123",
"menge": 2,
"shop": "DE"
}
}
```
```json Salesforce Flow theme={"system"}
{
"LeadSource": "Claude",
"Email": "buyer@example.com",
"Name": "Alex Buyer",
"Id": "00Qxx0000012345",
"Amount": 8500,
"CurrencyIsoCode": "USD"
}
```
## Daily batch import
If you prefer a daily job, send up to `1000` responses at once with the bulk API.
```bash theme={"system"}
curl --request POST \
--url "https://api.finseo.ai/v1/projects/PROJECT_ID/attribution/bulk" \
--header "Authorization: Bearer $FINSEO_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"responses": [
{
"channelId": "AI Search",
"respondentEmail": "kunde@example.com",
"respondentExternalId": "BESTELLUNG-12345",
"dealValue": 1234.56,
"dealCurrency": "EUR"
}
]
}'
```
See the [Bulk Create Attributions API](/api-reference/attribution/bulk) for the full reference.
## Receive attribution events
You can configure an outbound webhook URL in Attribution settings. Finseo sends an event to your URL whenever a new response is saved.
```json theme={"system"}
{
"event": "attribution.response.created",
"data": {
"id": "response-id",
"channel_id": "ai_chatgpt",
"channel_label": "ChatGPT",
"channel_category": "ai_search",
"respondent_email": "kunde@example.com",
"respondent_name": "Max Mustermann",
"deal_value": 1234.56,
"deal_currency": "EUR",
"source": "webhook",
"created_at": "2026-07-07T10:00:00Z"
},
"project_id": "PROJECT_ID",
"timestamp": "2026-07-07T10:00:01Z"
}
```
If you add an outbound webhook secret, Finseo signs the JSON body with an `X-FinSEO-Signature` header using HMAC-SHA256.
## Rate limits
* Webhook endpoint: **120 requests per minute** per project.
* Snippet collect endpoint: **60 requests per minute** per visitor IP.
Requests over the limit receive `429` and can safely be retried after a minute.
## Troubleshooting
Every incoming webhook request is logged with its parse result in **Attribution → Webhook logs** — including rejected requests. The statuses:
| Status | Meaning |
| ------------------- | ------------------------------------------------------------------------------------------------ |
| `stored` | Attribution response saved. |
| `stored_conversion` | Order-only payload saved as a conversion. |
| `parse_failed` | No attribution field or order data recognized — a workflow was created for manual field mapping. |
| `invalid_token` | The `token` query parameter is missing or wrong — copy the URL from the dashboard again. |
| `error` | Invalid body or server error. |
## Best practices
* Add the attribution question close to conversion, such as signup, demo request, checkout, or lead qualification.
* Keep answer options stable across countries. Translate labels for users if needed, but keep webhook values consistent.
* Send the original paid currency in `dealCurrency`; Finseo can still aggregate and map values.
* Include a stable `respondentExternalId` such as order ID, CRM lead ID, contact ID, or deal ID.
* Put product, SKU, market, campaign, and other business context in `metadata`.
* Send one event per lead, order, or deal. Avoid sending every page view as attribution.
# API Authentication & API Keys
Source: https://docs.finseo.ai/authentication
How to authenticate with the Finseo API using API keys.
# Authentication
All API requests require a valid API key in the `Authorization` header.
## Getting your API key
1. Go to [Settings > API](https://app.finseo.ai/settings/api) in the Finseo dashboard
2. Click **Create API Key**
3. Choose a name, scopes, and optionally restrict to specific projects
4. Copy the key immediately - it will only be shown once
## Using your key
```bash cURL theme={"system"}
# Keep the key out of your shell history: export it once, then reference it
export FINSEO_API_KEY=" API>"
curl -H "Authorization: Bearer $FINSEO_API_KEY" \
https://api.finseo.ai/v1/projects
```
```python Python theme={"system"}
import requests
headers = {"Authorization": "Bearer YOUR_API_KEY"}
response = requests.get(
"https://api.finseo.ai/v1/projects",
headers=headers
)
```
```javascript Node.js theme={"system"}
const response = await fetch("https://api.finseo.ai/v1/projects", {
headers: { Authorization: "Bearer YOUR_API_KEY" },
});
```
## Verifying a key
`GET /v1/me` returns the account behind a key. Use it to check that a key is valid, to show
users which account they connected, and to read the key's scopes — it answers independently of
whether the account has any projects yet, which makes it the right endpoint for integrations
and connection tests.
```bash theme={"system"}
curl -H "Authorization: Bearer $FINSEO_API_KEY" https://api.finseo.ai/v1/me
```
```json theme={"system"}
{
"data": {
"id": "6a81e088f8ef06e062c40633",
"email": "you@example.com",
"accountName": "Your Company",
"tier": "Business",
"projectCount": 1,
"scopes": ["read", "write"],
"environment": "live"
}
}
```
An invalid or revoked key returns `401` with error code `UNAUTHORIZED`.
## Scopes
API keys can have one or more scopes:
| Scope | Description |
| -------- | ------------------------------------------------------------ |
| `read` | Read data (projects, prompts, metrics, competitors, sources) |
| `write` | Modify data (create prompts, update tags, manage projects) |
| `export` | Bulk export tracking data |
## Project restrictions
Optionally restrict a key to specific projects. A key with no project restrictions can access all projects owned by your account.
## Key security
Never expose API keys in client-side code or public repositories.
* Keys are hashed with SHA-256 before storage - we never store plaintext
* Rotate keys regularly and revoke compromised keys immediately
* Use test keys for development, live keys for production
# Track AI Crawlers with Bot Analytics
Source: https://docs.finseo.ai/bot-analytics
Upload server logs to see how AI crawlers access your website.
# Bot Analytics
Bot Analytics shows which AI crawlers visit your site, which pages they request, and whether those requests succeed. Use it to answer practical questions:
* Can ChatGPT, Claude, Perplexity, Google, and other AI crawlers reach your important pages?
* Which URLs are crawled most often?
* Are bots hitting redirects, 404s, or server errors?
* Did an upload add new data, or was it already imported before?
## What you need
You need a server access log from the website you want to analyze. Finseo accepts `.log` and `.txt` files and auto-detects the format from the first lines.
The log must include the request User-Agent. Without the User-Agent, Finseo cannot reliably tell whether a request came from ChatGPT, Claude, Perplexity, Googlebot, or a normal browser.
## Upload a log file
1. Open **Bot Analytics** in the dashboard.
2. Select the project you want to analyze.
3. Click **Upload Logs**.
4. Drop a `.log` or `.txt` file into the upload dialog.
5. Wait for processing to finish.
Finseo stores only detected bot visits. Duplicate bot visits are skipped automatically, so you can re-upload overlapping files without double-counting the same requests.
Large files are supported up to `1GB`. Files above `50MB` are queued for background processing.
## Supported formats
Finseo currently detects Nginx, Apache combined access logs, Cloudflare-style logs, and a custom fallback format.
### Nginx combined access log
```text theme={"system"}
23.98.142.45 - - [03/Oct/2025:14:23:11 +0000] "GET /blog/ai-seo-guide HTTP/1.1" 200 15234 "https://www.google.com/" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; ChatGPT-User/1.0; +https://openai.com/bot"
```
Expected fields:
* IP address
* Timestamp in `[DD/Mon/YYYY:HH:mm:ss +0000]`
* HTTP method and path
* HTTP status code
* Response size in bytes
* Referrer
* User-Agent
### Apache combined access log
```text theme={"system"}
52.70.240.171 - - [03/Oct/2025:14:28:10 +0000] "GET /pricing HTTP/1.1" 200 18422 "-" "Mozilla/5.0 (compatible; ClaudeBot/1.0; +https://www.anthropic.com)"
```
Apache "common" logs without a User-Agent are not enough for bot classification. Configure Apache to use the combined log format before exporting.
### Cloudflare-style log
```text theme={"system"}
2025-10-03T14:31:22Z 44.220.185.12 GET /docs 200 9310 "-" "Mozilla/5.0 AppleWebKit/537.36 (KHTML, like Gecko); compatible; PerplexityBot/1.0; +https://perplexity.ai/bot"
```
Expected order:
```text theme={"system"}
timestamp ip method path status bytes "referrer" "user-agent"
```
### Custom fallback
Finseo can also parse lines where the IP appears first, followed by a quoted request, status, size, and a quoted User-Agent.
```text theme={"system"}
13.65.138.112 app "GET /features HTTP/1.1" 200 12482 "ChatGPT-User/1.0"
```
If your format is different, export or transform it into one of the examples above before uploading.
Custom Nginx formats with extra fields, such as request timing fields between the byte count and referrer, may not parse. Export a standard combined access log when possible.
## How to get logs
```bash Nginx theme={"system"}
# Common locations
ls /var/log/nginx/
# Copy the current access log
cp /var/log/nginx/access.log ./finseo-access.log
# Optional: compress first, then extract locally before upload
gzip -k ./finseo-access.log
```
```bash Apache theme={"system"}
# Debian/Ubuntu
cp /var/log/apache2/access.log ./finseo-access.log
# RHEL/CentOS/Amazon Linux
cp /var/log/httpd/access_log ./finseo-access.log
```
```bash Docker theme={"system"}
# Replace container_name with your web server container
docker logs container_name > finseo-access.log
```
For managed hosts, look for **Access logs**, **Raw logs**, **HTTP logs**, or **Web server logs** in your hosting dashboard. Download the unfiltered access log, not only error logs.
## Recommended time window
Upload the last `30` to `90` days first. That is usually enough to see crawler patterns and error rates. After the first upload, you can add new logs weekly or monthly.
## What Finseo extracts
For each detected bot request, Finseo stores:
* Bot platform and bot name
* IP address and User-Agent
* Request path and query parameters
* HTTP status code
* Response size
* Referrer
* Visit timestamp
The dashboard then groups this into:
* **Bot visits over time**: trend by bot and date.
* **Crawled pages**: URLs AI bots reached most often.
* **Performance**: response status and response-size patterns.
* **Status codes**: successful `2xx`, redirects `3xx`, client errors `4xx`, and server errors `5xx`.
The current log-upload parser focuses on crawl volume, URLs, response sizes, and HTTP status codes. It does not currently extract response-time fields from custom logs.
## Sync integrations
Instead of uploading logs manually, you can stream bot visits automatically. The **Sync** tab connects your CDN directly to Finseo:
Stream AI crawler visits in near real-time — via Worker (all plans) or Logpush (Enterprise). One-time setup, no more manual uploads.
Manual `.log` and `.txt` upload remains available and can be combined with a sync integration — duplicate visits are skipped automatically.
## Troubleshooting
Check that the file includes User-Agent values and that the time window contains requests from known crawlers such as `ChatGPT-User`, `GPTBot`, `ClaudeBot`, `Claude-Web`, `PerplexityBot`, `Googlebot`, `Bingbot`, `Applebot`, `AhrefsBot`, or `SemrushBot`.
Make sure you exported the combined access log. A short Apache common log line usually lacks referrer and User-Agent fields, which are required for bot detection.
Finseo deduplicates visits by bot, timestamp, IP, and page path. Re-uploading overlapping files should not inflate your numbers.
Files above `50MB` can be processed in the background. Check back after a few minutes. If the status fails, split the log into smaller date ranges and upload again.
# Changelog
Source: https://docs.finseo.ai/changelog
Latest changes to the Finseo API.
# Changelog
## September 2026
### Model settings and account limits are now identical in the API and the dashboard
Prompts created via the API could run on models that were not enabled in the project's Model Settings, so the dashboard filters showed fewer models than the prompts actually tracked. The API now uses the project's model settings as its source of truth and applies every limit the dashboard applies, with the same error codes. See [Automate a pitch](/api-reference/guides/automate-pitch) for the end-to-end agency flow.
* **`PUT /projects/{projectId}`** accepts `models` — the API counterpart of the Model Settings page. Replaces the set, re-syncs every prompt of the project (`syncedPromptCount`) and enforces the plan model cap, the Brand prompt budget and the Agency answer projection (`meteredNotice` on the top package)
* **`GET /projects`**, **`GET /projects/{projectId}`** and **`POST /projects`** return `models` (project setting → account default) and `language`
* **`POST /projects/{projectId}/prompts`**: `models` is optional and defaults to the project's models; an explicit list must be a subset of them, otherwise `400 model_not_enabled`. New Agency answer-projection guard, same as the dashboard
* **`POST /projects`** applies the dashboard's project gates: pitch projects require an Agency account and a free pitch slot, client projects a free slot on Agency packages (`agency_limit`), and the plan project cap on Brand plans
* **Errors**: limit violations now return `403 FORBIDDEN` with a machine-readable `error.details.reason` (`agency_limit`, `prompt_budget_exceeded`, `prompt_limit`, `model_limit`, `model_not_available`, `pitch_prompt_limit`, `pitch_expired`, `pitch_project_limit`) instead of a generic `500`
* **MCP** `list_projects` returns `language`, `isPitch` and `models` per project
### Visibility = named OR cited; new Mention Rate and Citation Rate
Finseo now separates the two ways a brand appears in an AI answer — **named in the answer text** and **cited as a source** — and reports them as distinct KPIs. See [KPIs explained](/getting-started/kpis).
* **Visibility redefined**: an answer counts as visible when the brand is named in the text **or** its own domain (or a configured domain alias) is cited as a source. Previously only text mentions counted, so Visibility can be slightly higher than before for brands whose sites are cited without being named
* **New KPIs**: **Mention Rate** (share of answers naming the brand) and **Citation Rate** (share of answers citing the own domain), both on the same denominator as Visibility. They overlap, so Visibility ≤ Mention Rate + Citation Rate
* **REST `/metrics`** returns `mentionRate`, `citationRate`, `cited` per period plus `mentionRateChange`, `citationRateChange`, `citedChange`; `responseVisibilityRate` now uses the named-or-cited definition
* **REST `/metrics/timeseries`** adds `cited` per day (`null` for days served from rollups without citations)
* **REST `/competitors`** adds `mentionRate`, `mentionRateChange`, `totalCitations`, `citationRate`, `citationRateChange` and `visibilityIsMentionOnly`; `visibilityRate`/`visibleResults` now use the named-or-cited definition. Default `sortBy` is `visibility`
* **REST `/prompts`** adds `mentionRate` and `citationRate` per prompt; `isVisible` uses the named-or-cited definition
* **MCP**: `get_visibility_metrics` and `get_visibility_timeseries` return `mentionRatePercent`, `citationRatePercent` and `ownDomainCitedAnswers`; `get_competitor_ranking` returns `mentionRatePercent`, `citationRatePercent` and `visibilityIsMentionOnly`; `list_prompts` returns `mentionRatePercent` and `citationRatePercent`. `visibilityRatePercent` everywhere follows the named-or-cited definition and the tool notes explain the split
* **Domain aliases**: additional domains for citation matching (e.g. country TLDs, shop subdomains) can be configured per project in the dashboard settings; they apply to all prompts of the project
### Fix: prompts created via `POST /prompts` are processed immediately
Prompts added through the REST API were saved but not queued for the workers, so they only got picked up by the nightly sweep — and on a fresh project they were stored without the project's domain and brand name, which meant the brand could never be recognised in answers.
* Prompts are now queued right away (`enqueued: true` in the response); first answers typically arrive within minutes
* The prompt inherits the project's domain, brand name (project `name`), synonyms, domain aliases and tracking frequency. Projects without a `websiteUrl` are rejected with `400`
* `language` now defaults to the project language and is normalised to the dashboard spelling (`de` → `DE`), so the country filter matches prompts added via the API
### Pitch projects + required language
* **Pitch projects via API**: `POST /v1/projects` accepts `isPitch` and `pitchDurationDays` (`1`, `7` or `14`, default 14) — no project fee, capped at 50 prompts, auto-paused when the pitch window closes. Pitch slots are capped per agency package (250 on Agency Starter, 500 on Agency Studio)
* **Convert won pitches**: `PUT /v1/projects/{projectId}` with `{"convertFromPitch": true}` turns a pitch into a full client project (checks a free client slot and the plan's answer budget, then reactivates paused prompts)
* **`language` is now required** on `POST /v1/projects` — one of 22 supported codes (`en`, `de`, `fr`, `es`, `it`, `nl`, `pt`, `pl`, `sv`, `da`, `tr`, `ja`, `no`, `fi`, `cs`, `ru`, `zh`, `zh-tw`, `ko`, `hi`, `ar`, `he`). Previously the language was inferred from a site crawl, which often defaulted to English for non-English markets
* **`GET /v1/projects`** now returns `isPitch` on every project, plus `pitchDurationDays` and `pitchExpiredAt` on pitch projects
## August 2026
### Clear position semantics + full competitor KPI set
* **MCP `get_competitor_ranking`** now returns the full dashboard KPI set per competitor: `avgMentionOrder` (ordinal Position KPI, 1 = named first), `mentionDepthPercent`, `shareOfVoicePercent`, `firstMentionSharePercent`, `top3MentionSharePercent`, head-to-head (`h2hYouFirstPercent`) and citation share — with a `note` explaining each metric
* **MCP field renames for clarity**: the text-depth metric formerly reported as `avgPositionPercent`/`avgPosition` is now `mentionDepthPercent` across `get_visibility_metrics`, `get_visibility_timeseries`, `list_prompts` and `get_prompt_details`; `get_visibility_timeseries` additionally returns the per-day ordinal `avgMentionOrder`
* **REST `/competitors`** now additionally returns `avgMentionOrder` (+change), `shareOfVoicePercent` (+change), `firstMentionSharePercent` and `top3MentionSharePercent`; `averagePosition` (mention depth) is unchanged for backwards compatibility
### Custom date ranges
* **`startDate`/`endDate` query parameters** (YYYY-MM-DD, always together) on `/metrics`, `/metrics/timeseries`, `/competitors`, `/sources` and `/export` — absolute ranges that override the relative `timeframe`
* **MCP tools accept `startDate`/`endDate`** on all analytics tools (`get_visibility_metrics`, `get_visibility_timeseries`, `get_competitor_ranking`, `get_top_sources`, `get_query_fanouts`, `get_competitor_gap_analysis`, `get_competitor_h2h`, `get_sentiment_overview`)
* `/metrics` compares a custom range against the equally long period immediately before it
## March 2026
### v1.0.0 - Initial Release
* **Customer API** with 14 endpoints for projects, prompts, metrics, competitors, sources, tags, and export
* **API Key authentication** with granular scopes (read, write, export) and project restrictions
* **Rate limiting** per plan (Starter: 60/min, Pro: 180/min, Enterprise: 600/min)
* **MCP Server** for Claude Desktop and Cursor integration
# Track AI Bot Traffic via Cloudflare
Source: https://docs.finseo.ai/cloudflare-bot-traffic
Stream AI crawler visits from Cloudflare to Finseo in near real-time — via Worker (all plans) or Logpush (Enterprise).
# Cloudflare Bot Traffic
Instead of uploading server logs manually, you can connect Cloudflare once and Finseo receives every AI and search crawler visit automatically, in near real-time. The connection lives in **Bot Analytics → Sync → Cloudflare**.
There are two connection methods:
| | Cloudflare Worker | Logpush |
| --------------- | ------------------------------------------------------- | ----------------------------------------------------------------------- |
| Cloudflare plan | All plans (including Free) | Enterprise only |
| Latency | Seconds | Minutes (batched) |
| How it works | A lightweight Worker on your zone forwards bot requests | Cloudflare pushes `http_requests` log batches to a Finseo HTTP endpoint |
| Recommended | Yes | If you are on Enterprise and prefer log pipelines |
Both methods only transmit requests from known AI and search crawlers (matched by User-Agent). Regular visitor traffic is never sent to Finseo.
## Which bots are tracked
Finseo receives requests whose User-Agent matches one of these crawlers:
`GPTBot`, `OAI-SearchBot`, `ChatGPT-User`, `ClaudeBot`, `Claude-Web`, `Claude-SearchBot`, `anthropic-ai`, `PerplexityBot`, `Perplexity-User`, `Google-Extended`, `GoogleOther`, `Googlebot`, `Bingbot`, `CCBot`, `Bytespider`, `Amazonbot`, `Applebot`, `meta-externalagent`, `FacebookBot`, `DuckAssistBot`, `cohere`, `MistralAI`, `YandexBot`, `DuckDuckBot`
## Before you start
For both methods you need your IDs from the Cloudflare dashboard. Open [dash.cloudflare.com](https://dash.cloudflare.com), select your domain, and find the **API** section on the **Overview** page (right sidebar):
* **Zone ID** — always required.
* **Account ID** — required for the Worker method.
You also create a Cloudflare **API token** ([dash.cloudflare.com/profile/api-tokens](https://dash.cloudflare.com/profile/api-tokens) → **Create Token** → **Create Custom Token**). Finseo uses the token once during setup and never stores it.
## Method 1: Cloudflare Worker (recommended)
Works on every Cloudflare plan. Finseo deploys a small Worker named `finseo-bot-traffic` on your zone. The Worker passes every request through unchanged and — only when the User-Agent matches a known crawler — reports the visit to Finseo in the background. Visitor responses are never delayed or altered.
### Quick setup
1. Create a custom API token with these permissions:
* **Account → Workers Scripts → Edit**
* **Zone → Workers Routes → Edit**
* **Zone → Zone → Read**
2. In Finseo, open **Bot Analytics → Sync → Cloudflare → Connect**.
3. Select **Cloudflare Worker**.
4. Paste the API token, your **Account ID**, and your **Zone ID**.
5. Click **Deploy Worker**.
Finseo uploads the Worker and adds a route covering your whole zone (`*yourdomain.com/*`, apex and subdomains). The integration shows **Awaiting first push** until the first bot visit arrives, then switches to **Connected**.
### Manual setup
If you prefer not to enter an API token, deploy the Worker yourself:
1. In the Finseo connect dialog, select **Cloudflare Worker** and copy the **Worker script** (your ingest token is already included).
2. In the Cloudflare dashboard, go to **Workers & Pages → Create → Worker**, paste the script, and deploy.
3. Open the Worker's **Settings → Domains & Routes** and add the route `*yourdomain.com/*` for your zone.
Refer to Cloudflare's [Workers dashboard guide](https://developers.cloudflare.com/workers/get-started/dashboard/) for details.
### Worker limits
The Workers Free plan includes `100,000` requests per day ([Cloudflare Workers pricing](https://developers.cloudflare.com/workers/platform/pricing/)). The route counts every request on your zone against this limit, not only bot requests. Above the limit, Cloudflare serves your traffic normally without running the Worker — your site is never affected, Finseo just stops receiving reports until the daily reset. High-traffic sites should use the Workers Paid plan or Logpush.
## Method 2: Logpush (Enterprise)
[Cloudflare Logpush](https://developers.cloudflare.com/logs/logpush/) streams the `http_requests` dataset to an HTTP endpoint. The dataset is only available on the **Enterprise plan**.
### Quick setup
1. Create a custom API token with the permission:
* **Zone → Logs → Edit**
2. In Finseo, open **Bot Analytics → Sync → Cloudflare → Connect**.
3. Select **Logpush**.
4. Paste the API token and your **Zone ID**.
5. Click **Create Logpush job**.
Finseo creates the job via the Cloudflare API with these settings:
* Dataset `http_requests` with an HTTP destination pointing at your project's ingest endpoint (authenticated via header token).
* A filter so only requests from the crawlers listed above are pushed.
* Timestamps in RFC 3339, batches of up to `5 MB` / `1,000` records.
Cloudflare sends a test upload immediately after the job is created — the integration switches to **Connected** as soon as it arrives.
### Manual setup
1. In the Finseo connect dialog, select **Logpush** and copy the **HTTP destination** (`destination_conf`) — it contains your ingest endpoint and authentication header.
2. In the Cloudflare dashboard, go to **Analytics & Logs → Logpush → Create a Logpush job**.
3. Choose **HTTP destination** and paste the copied destination.
4. Select the dataset **HTTP requests**.
5. Optional but recommended: under **If logs match**, filter on `ClientRequestUserAgent contains` the crawler names above — otherwise Cloudflare pushes all requests and Finseo discards the non-bot lines.
6. Submit the job.
Refer to Cloudflare's [HTTP destination guide](https://developers.cloudflare.com/logs/logpush/logpush-job/enable-destinations/http/) for details.
Cloudflare allows a maximum of `4` Logpush jobs per zone. If job creation fails with `exceeded max jobs allowed`, delete an unused job first.
## What Finseo receives
Both methods transmit the same fields per bot request:
* IP address and User-Agent (used to verify the bot identity)
* Host, method, path, and query string
* Referrer
* HTTP status code and response size
* Country, city, and region
* Timestamp and time to first byte
Visits are deduplicated and appear in **Bot Analytics** alongside data from manual log uploads.
## Disconnect
Click **Manage → Disconnect** on the Cloudflare card. This invalidates the ingest token, so Cloudflare deliveries are rejected immediately. Also remove the Worker route (or the Worker itself) or the Logpush job in your Cloudflare dashboard to stop the pushes at the source.
## Troubleshooting
Finseo verifies the token against the Cloudflare API before using it. Make sure the token is active and has exactly the permissions listed for your method — Worker: **Workers Scripts: Edit** (account), **Workers Routes: Edit** and **Zone: Read** (zone); Logpush: **Logs: Edit** (zone).
The `http_requests` dataset requires the Enterprise plan. On other plans, Cloudflare rejects the job — use the Worker method instead. On Enterprise, check the 4-jobs-per-zone limit.
Worker: the status switches on the first bot visit — depending on your crawl volume this can take a few hours. Check under **Workers & Pages** that the Worker is deployed and the route `*yourdomain.com/*` exists. Logpush: Cloudflare sends a test upload right away; if nothing arrives within minutes, check the job status under **Analytics & Logs → Logpush**.
If another Worker is already routed on `*yourdomain.com/*`, the deployment keeps the existing route. Route the `finseo-bot-traffic` Worker on a more specific pattern, or call the Finseo report from your existing Worker.
# KPIs & Metrics Explained — AI Visibility Measurement
Source: https://docs.finseo.ai/getting-started/kpis
Every Finseo metric explained in plain language, with formulas and worked examples — Visibility, Mention Rate, Citation Rate, Share of Voice, Position, Mention Depth, Citations, Sentiment and more.
# KPIs & metrics
Finseo measures how visible your brand is in AI answers from ChatGPT, Perplexity, Gemini, Claude and other models. This page defines every metric precisely — what it counts, how it is calculated, and what a good number looks like.
All metrics are available in the dashboard, the [REST API](/api-reference/metrics/daily) and the [MCP server](/mcp/overview), and every metric shows a change indicator comparing the selected timeframe to the previous period of the same length.
## The running example
The formulas below all use this example: you track **20 prompts** across **2 models**, so one day produces **40 AI answers**. Your brand is **Acme**, your domain is `acme.com`.
* Acme is **named in the text** of **18** of the 40 answers.
* `acme.com` is **cited as a source** in **8** answers — 6 of those also name Acme, 2 only link to it.
* Acme is therefore visible in **20** answers (18 named + 2 cited-only).
* Across all 40 answers, AI models name brands **120 times** in total (all brands combined).
## Presence metrics
A brand can show up in an AI answer in two ways: the model **names** it in the answer text, or it **cites** one of the brand's domains as a source. Finseo tracks both and reports them separately — and combines them into Visibility.
### Visibility
**The share of AI answers in which your brand is visible at all — named in the text OR cited as a source.**
```text theme={"system"}
Visibility = (answers naming your brand OR citing your domain ÷ all tracked answers) × 100
```
Example: Acme is named in 18 answers and cited-only in 2 more → visible in 20 of 40 → **Visibility = 50%**.
Visibility is the headline metric: it answers "when someone asks AI about my category, how often am I part of the answer?" It counts each answer once, no matter how often you are named or linked inside it. Because it is a union, Visibility is never lower than Mention Rate or Citation Rate, and never higher than their sum.
### Mention Rate
**The share of AI answers that name your brand in the answer text.**
```text theme={"system"}
Mention Rate = (answers naming your brand ÷ all tracked answers) × 100
```
Example: 18 of 40 answers → **Mention Rate = 45%**. Mention Rate is the classic "does the AI talk about me?" metric — it ignores whether your site was used as a source.
### Citation Rate
**The share of AI answers that cite one of your domains as a source.**
```text theme={"system"}
Citation Rate = (answers citing your domain ÷ all tracked answers) × 100
```
Example: 8 of 40 answers → **Citation Rate = 20%**. Your domain is matched against the project domain plus any **domain aliases** configured in the project settings (e.g. `acme.de`, `shop.acme.com`).
Mention Rate and Citation Rate are not additive: 45% + 20% = 65%, but Visibility is 50%, because 6 answers count in both.
### Visibility Mix
The dashboard's *Breakdown* view splits Visibility into three non-overlapping segments that add up exactly to Visibility:
| Segment | Meaning | Example |
| --------------------- | ---------------------------------------------------------- | ---------------- |
| **Mentioned + Cited** | Named in the text and your domain cited | 6 answers → 15% |
| **Mentioned only** | Named, but your site was not used as a source | 12 answers → 30% |
| **Cited only** | Your site was used as a source, but the brand is not named | 2 answers → 5% |
"Cited only" is the most actionable segment: the model already trusts your content but does not attribute it to you — usually a sign that brand and product names are missing from the cited pages.
### Mentions
**The number of AI answers that name your brand in the selected timeframe.**
Each answer counts once, no matter how often it repeats your name. Mentions is the absolute count behind Mention Rate: **18 mentions** in our example, so Mention Rate = 18 ÷ 40 = 45%. Use Mentions when you need volumes (e.g. for reporting), Mention Rate when you compare periods or models with different answer counts.
### Model Visibility
**Visibility broken down per AI model** (ChatGPT, Perplexity, Gemini, Claude, Grok, Mistral, DeepSeek, Copilot, Google AI Overview, Google AI Mode).
Models draw on different sources and training data, so it is normal to be strong on one model and invisible on another. A gap between models usually points to which sources each model relies on — check [Top Sources](/api-reference/sources/ranking) per model to find out where to invest.
## Competitive metrics
### Share of Voice (SoV)
**Your slice of the total brand conversation — your answers as a percentage of all brand appearances across every brand.**
```text theme={"system"}
SoV = (answers naming your brand ÷ answer-appearances of ALL brands) × 100
```
SoV differs from Visibility because the denominator is the whole market, not your prompt set. Suppose in our example the 40 answers produce 90 brand-appearances across all detected brands, 18 of which are Acme → **SoV = 20%**, even though Visibility is 45%. You can have high Visibility and low SoV when competitors are mentioned alongside you in almost every answer.
Finseo shows SoV against two denominators so the number is never ambiguous:
| Variant | Denominator |
| ------------------ | ----------------------------------------------------------------------------- |
| **All brands** | Every brand the AI models actually named — the full market as AI sees it |
| **Tracked brands** | Only your brand plus the competitors you track — your defined competitive set |
### Average Position
**The average order in which your brand is named among the brands in an answer.** Displayed as an absolute value, e.g. `#2.6`. Lower is better.
If an answer recommends "1. Acme, 2. Beta, 3. Gamma", Acme has position #1 in that answer. Averaged across all answers where you appear:
```text theme={"system"}
Avg Position = sum of your ordinal positions ÷ answers where you appear
```
Example: Acme is named first in 9 answers, second in 6, fourth in 3 → (9×1 + 6×2 + 3×4) ÷ 18 = **#1.8**.
Position matters because AI answers behave like rankings: the first brand named typically frames the recommendation. Ties (two brands named in the same breath) share the same ordinal.
### #1 Share
**The percentage of your answers in which you are the FIRST brand named.**
```text theme={"system"}
#1 Share = (answers where your position = 1 ÷ answers where you appear) × 100
```
Example: first in 9 of 18 answers → **#1 Share = 50%**. This is the "pole position" metric — it isolates how often you lead the answer rather than just appearing in it.
### Top-3 Share
**The percentage of your answers in which you are among the first three brands named.**
```text theme={"system"}
Top-3 Share = (answers where your position ≤ 3 ÷ answers where you appear) × 100
```
Example: 15 of Acme's 18 answers have it in the top three → **Top-3 Share = 83%**. Useful for long list-style answers where being in the opening cluster matters more than being strictly first.
### Head-to-Head (H2H)
**Against one specific competitor: the percentage of answers naming BOTH brands where yours is named first.** Ties are excluded.
```text theme={"system"}
H2H win rate = (shared answers where you are first ÷ shared answers with a decided order) × 100
```
Example: Acme and Beta appear together in 10 answers; Acme is named first in 7 → **H2H vs Beta = 70%**. H2H removes the noise of answers where only one of you appears — it is the cleanest "who does AI prefer?" comparison.
## Placement metrics
### Mention Depth
**How deep in the answer text your mention appears, on average.** 0% = the very top of the answer, 100% = the very end. Lower is better.
```text theme={"system"}
Mention Depth = character offset of the mention ÷ total answer length × 100
```
Example: your mention starts at character 300 of a 1,200-character answer → depth = 25% for that answer. A brand can hold Average Position #1 with 40% depth when answers open with a long preamble before naming any brands — that is why Finseo reports order and depth as separate metrics.
## Source metrics
### Citations
**The number of AI answers that cited one of your domains as a source.** Each answer counts once, even if it links your domain several times. Citations is the absolute count behind [Citation Rate](#citation-rate): **8 citations** in our example → 8 ÷ 40 = 20%.
Citations measure something different from Mentions: a mention is the AI *talking about* you, a citation is the AI *sourcing from* you. You can be mentioned without being cited (the model knows you from training data) and cited without being mentioned (your content informs an answer about someone else). Both count toward [Visibility](#visibility).
### Citation Share
**Your citations as a percentage of all brands' citations in the project.**
```text theme={"system"}
Citation Share = (answers citing your domains ÷ answers citing any tracked brand's domains) × 100
```
Example: AI answers cite Acme's domains 30 times and all tracked brands' domains 150 times → **Citation Share = 20%**. This is the source-side equivalent of Share of Voice: it shows who owns the underlying evidence AI answers are built on.
## Quality metrics
### Sentiment
**How positively AI models describe your brand, scored 0–100.**
Finseo analyzes the language around each mention — words like "reliable", "market leader" or "excellent support" score positive; "expensive", "complicated" or "mixed reviews" score negative. Scores roughly read as:
| Score | Reading |
| ------ | ------------------------------------------------------------------------------------- |
| 80–100 | Strongly positive framing |
| 60–79 | Positive |
| 40–59 | Neutral / mixed |
| 0–39 | Critical framing — investigate the [Sentiment page](/sentiment) for the exact phrases |
Sentiment is tracked per aspect (price, quality, support, …) and per competitor, so you can see not just *that* perception dipped but *which* aspect drove it.
## Reading the metrics together
The metrics form a funnel — each answers a different question:
| Question | Metric |
| ------------------------------------------------ | ----------------------------------- |
| Am I part of the answer at all (named or cited)? | Visibility |
| Does the AI talk about me? | Mention Rate, Mentions |
| Does the AI source from me? | Citation Rate, Citations |
| Named, cited, or both? | Visibility Mix |
| How much of the total conversation is mine? | Share of Voice |
| When I appear, do I lead? | Avg Position, #1 Share, Top-3 Share |
| Who wins when we appear together? | Head-to-Head |
| How early in the text am I named? | Mention Depth |
| Who owns the evidence AI answers are built on? | Citation Share |
| How am I talked about? | Sentiment |
A common pattern: Visibility is fine but Share of Voice is falling. That means the market conversation is growing faster than your presence in it — competitors are being added to answers you used to dominate. Check the [competitor gap analysis](/mcp/overview) to see which prompts drive the shift.
## Accessing metrics programmatically
* **REST API** — [`GET /v1/projects/{projectId}/metrics`](/api-reference/metrics/daily) (`visibilityRate`, `mentionRate`, `citationRate`, …), [`/metrics/timeseries`](/api-reference/metrics/timeseries) and [`/competitors`](/api-reference/competitors/ranking)
* **MCP server** — `get_visibility_metrics`, `get_visibility_timeseries`, `get_competitor_ranking`, `get_competitor_h2h`, `get_sentiment_overview` and more; see the [MCP overview](/mcp/overview)
# Choose AI Models to Track
Source: https://docs.finseo.ai/getting-started/models
Configure which AI models Finseo uses for prompt tracking.
# AI models
AI model settings control where Finseo runs your tracking prompts. More models give broader coverage, but they also increase the number of AI answers generated per prompt.
## Available models
Finseo supports the following model channels in the dashboard:
| Model ID | Description |
| ---------------- | ----------------------------------------------------- |
| `chatgpt` | ChatGPT GUI/UI-style tracking. |
| `chatgpt_gui` | ChatGPT API-style tracking. |
| `perplexity` | Perplexity answers and source citations. |
| `ai_overview` | Google AI Overview-style result tracking. |
| `google_ai_mode` | Google AI Mode-style result tracking where available. |
| `claude` | Claude answers. |
| `grok` | Grok answers. |
| `mistral` | Mistral answers. |
| `deepseek` | DeepSeek answers. |
| `gemini` | Gemini answers. |
| `copilot` | Microsoft Copilot answers. |
## Default model selection
New accounts start with these defaults:
```json theme={"system"}
{
"chatgpt": true,
"perplexity": true,
"ai_overview": true,
"chatgpt_gui": false,
"google_ai_mode": false,
"claude": false,
"grok": false,
"mistral": false,
"deepseek": false,
"gemini": false,
"copilot": false
}
```
This gives you coverage across ChatGPT, Perplexity, and Google-style AI search without running every possible model.
## Account defaults vs project settings
Finseo supports two levels of model settings:
* **Account defaults** apply when a project has no custom model settings.
* **Project-specific settings** override the account defaults for one project.
Use project-specific settings when different brands, markets, or clients need different model coverage.
## Change enabled models
1. Open **Models**.
2. Select the project if you want project-specific settings.
3. Toggle the models you want to track.
4. Save the settings.
When you save project-specific settings, Finseo syncs existing tracking prompts in that project to the enabled model set. New prompts use the same enabled models by default.
## Model limits
Most plans can enable up to `3` models per prompt. Agency plans and custom enterprise quotes can allow more models.
If you hit the model limit, disable one model before enabling another. The limit is enforced when saving model preferences and when adding new prompts.
For agency accounts, model count affects projected monthly AI answers. Adding prompts across many models increases usage because each prompt is run once per enabled model.
## How model count affects results
The number of generated answers is roughly:
```text theme={"system"}
tracked prompts × enabled models × scheduled runs
```
Example:
```text theme={"system"}
100 prompts × 3 models = 300 AI answers per run
100 prompts × 6 models = 600 AI answers per run
```
Use more models when you need broad market coverage. Use fewer models when you want focused tracking, faster analysis, or lower usage.
## Choosing a model mix
Start with:
* `chatgpt` for broad assistant visibility.
* `perplexity` for citation-heavy AI search behavior.
* `ai_overview` for Google AI result visibility.
Then add more models when they matter to your audience:
* Add `claude` for B2B, enterprise, technical, or research-heavy markets.
* Add `gemini` or `google_ai_mode` when Google AI surfaces are strategically important.
* Add `grok`, `mistral`, or `deepseek` when your audience uses those platforms.
## API behavior
When you create prompts through the API, you can pass an explicit `models` array.
```json theme={"system"}
{
"prompt": "Best AI visibility tracking tools for agencies",
"models": ["chatgpt", "perplexity", "ai_overview"],
"language": "us",
"tags": ["agency", "comparison"]
}
```
If you omit `models`, Finseo uses the enabled project settings. If no project settings exist, it uses the account defaults.
See the [Create Prompt API](/api-reference/prompts/add) for the full reference.
# Set Up Prompt Tracking
Source: https://docs.finseo.ai/getting-started/prompts
Learn how to choose and add prompts that measure your AI visibility.
# Tracking prompts
Prompts are the questions Finseo runs across AI models to measure whether your brand appears, how it is described, which competitors are mentioned, and which sources are cited.
Good prompts should sound like real customer questions, not SEO keywords.
## Add a prompt
1. Open **AI Tracking**.
2. Click **Add Tracking Prompt**.
3. Select a **Location**.
4. Add one or more **Tags**.
5. Enter one or more prompts. Use one line per prompt.
6. Review the enabled AI models.
7. Click **Add prompts**.
Finseo saves the prompt and queues it for processing. Results appear after the worker pipeline finishes running the prompt across the enabled models.
## Add multiple prompts at once
Use line breaks to add several prompts from the same dialog.
```text theme={"system"}
What are the best SEO tools for content optimization?
List the top AI visibility platforms for B2B SaaS.
Which companies help ecommerce brands get mentioned in ChatGPT?
Compare Finseo alternatives for AI search tracking.
```
Each non-empty line is added as a separate prompt.
## Choose the right location
The **Location** controls the market context used for the AI search. AI responses can differ by country, language, and regional search behavior.
Choose the location that matches the audience you care about:
* Use `Germany` for German buyers and German-language visibility.
* Use `United States` for US buyers and English commercial prompts.
* Create separate prompts for separate markets if your product positioning differs by country.
If no location is provided through the API, Finseo falls back to `en`.
## Use tags
Tags help segment your visibility reports. Add them when you create prompts so you can filter and compare groups later.
Common tag patterns:
* `branded` and `unbranded`
* `top-of-funnel`, `comparison`, and `transactional`
* `de`, `us`, `uk`, or other market labels
* Product categories such as `crm`, `email-marketing`, or `pressure-washers`
* Campaign or customer segment labels
## Write better prompts
Strong prompts describe a real decision a buyer is trying to make.
```text Good theme={"system"}
What are the best tools to track brand visibility in ChatGPT?
Which CRM is best for a 50-person B2B SaaS team?
Compare Kärcher and Nilfisk pressure washers for home patios.
What software helps ecommerce teams understand AI search traffic?
```
```text Weak theme={"system"}
AI visibility
CRM
Kärcher
Best tool
```
## Recommended prompt mix
Start with `20` to `50` prompts per important market. Cover the full buyer journey:
| Type | Example | Why it matters |
| ------------- | ----------------------------------------------- | ---------------------------------------------------- |
| Problem-aware | `How can I see if ChatGPT recommends my brand?` | Measures demand before users know your category. |
| Category | `Best AI visibility tracking tools` | Shows whether you appear in shortlist-style answers. |
| Comparison | `Finseo vs Profound for AI search tracking` | Reveals competitive positioning. |
| Transactional | `Which AI SEO platform should an agency use?` | Captures bottom-funnel buying intent. |
| Brand | `What is Finseo and who is it for?` | Checks brand understanding and sentiment. |
## What happens after a prompt is added
Finseo runs the prompt across the enabled models for the project. It stores:
* Whether your brand was visible
* Mentions and position
* Competitor mentions
* Sentiment and phrases
* Cited sources
* Query fan-outs and related searches where available
* Product, claim, and comparison insights where available
New prompts are processed asynchronously. The dashboard shows processing states while results are being generated.
## API option
You can also create prompts through the API.
```bash theme={"system"}
curl --request POST \
--url https://api.finseo.ai/v1/projects/PROJECT_ID/prompts \
--header "Authorization: Bearer $FINSEO_API_KEY" \
--header "Content-Type: application/json" \
--data '{
"prompt": "What are the best AI visibility tracking tools?",
"models": ["chatgpt", "perplexity", "ai_overview"],
"language": "us",
"tags": ["unbranded", "comparison"]
}'
```
See the [Create Prompt API](/api-reference/prompts/add) for the full reference.
# Measure Human Traffic from AI Search
Source: https://docs.finseo.ai/human-traffic
Connect analytics data to measure visits, conversions, and revenue from AI platforms.
# Human Traffic
Human Traffic shows real website sessions that came from AI platforms such as ChatGPT, Claude, Perplexity, Gemini, Copilot, DeepSeek, Mistral, Meta AI, Grok, You.com, and Poe.
Use it to understand whether AI visibility turns into actual visitors, conversions, and revenue.
## What Human Traffic measures
Finseo reads your analytics data and filters sessions whose source looks like an AI platform.
The dashboard can show:
* Sessions from AI platforms
* Users from AI platforms
* Conversions
* Revenue
* Conversion rate
* Top AI traffic sources
* Trends over time
* Event-specific conversion counts
## Connect analytics
1. Open **Human Traffic**.
2. Select your project.
3. Click **Connect Analytics**.
4. Choose **Google Analytics 4** or **Piwik PRO**.
5. Complete the provider authorization flow.
6. Select the property or site that belongs to the project.
After the connection is saved, Finseo queries analytics data for the selected date range and filters for AI-related sources.
## Supported providers
Uses the GA4 Data API to read sessions, users, conversions, and purchase revenue by source and date.
Uses Piwik PRO reports with the same AI-source filtering logic.
## AI sources Finseo recognizes
Finseo normalizes source names into readable model names. Examples:
| Raw source contains | Displayed as |
| ---------------------------------- | ------------- |
| `chatgpt`, `openai`, `chat.openai` | ChatGPT |
| `claude`, `anthropic` | Claude |
| `perplexity`, `pplx` | Perplexity |
| `gemini`, `bard` | Google Gemini |
| `copilot`, `microsoft copilot` | Copilot |
| `deepseek` | DeepSeek |
| `mistral` | Mistral |
| `llama`, `meta.ai`, `meta-ai` | Meta AI |
| `grok`, `xai`, `x.ai` | Grok |
| `you.com` | You.com |
| `poe` | Poe |
Regular Google organic traffic is excluded unless it appears as an AI-specific source such as Google AI Mode or Gemini.
## Improve detection with UTM tags
AI platforms do not always send perfect referrer data. If you control links that appear in AI-optimized content, use UTM parameters so analytics can classify the source cleanly.
```text theme={"system"}
https://example.com/pricing?utm_source=chatgpt&utm_medium=ai&utm_campaign=ai_visibility
```
Recommended values:
| Parameter | Example |
| -------------- | ------------------------------------------------------ |
| `utm_source` | `chatgpt`, `perplexity`, `claude`, `gemini`, `copilot` |
| `utm_medium` | `ai` |
| `utm_campaign` | `ai_visibility`, `brand_mentions`, `comparison_pages` |
## Track conversions
Human Traffic can show conversions and event-specific conversion counts when your analytics property already records conversion events.
In GA4, mark the important events as key events or conversions, for example:
* `generate_lead`
* `sign_up`
* `purchase`
* `book_demo`
* `form_submit`
Then use Human Traffic to filter or compare AI-attributed conversions by event.
## Revenue
Revenue is read from the connected analytics provider. For GA4, Finseo uses purchase revenue where available.
If you do not see revenue:
* Check that ecommerce revenue is configured in GA4 or Piwik PRO.
* Check that purchase or deal events are connected to the same property.
* Confirm that AI-attributed sessions exist in the selected date range.
## Date ranges and metrics
You can switch the dashboard metric between:
* `sessions`
* `conversions`
* `revenue`
You can also use preset or custom date ranges. Finseo compares periods to show changes over time.
## Troubleshooting
Connect Google Analytics 4 or Piwik PRO for the selected project. Connections are project-specific, so connecting one project does not automatically connect every project.
Expand the date range first. Then check whether your analytics source names contain values like `chatgpt`, `perplexity`, `claude`, `gemini`, `copilot`, `deepseek`, or `mistral`.
Confirm that conversion events are configured in your analytics provider and that those events occurred in AI-attributed sessions.
Confirm that ecommerce or purchase revenue is sent to your analytics provider. Finseo cannot infer revenue if the provider does not store it.
## Human traffic vs bot traffic
Human Traffic and Bot Analytics answer different questions.
| Feature | What it measures | Data source |
| ------------- | --------------------------------------------------------- | ------------------ |
| Human Traffic | Real visitors, conversions, and revenue from AI platforms | GA4 or Piwik PRO |
| Bot Analytics | AI crawler requests to your website | Server access logs |
Use both together to see the full picture: crawlers show whether AI systems can access your content, and human traffic shows whether AI platforms send visitors and revenue.
# Introduction
Source: https://docs.finseo.ai/index
The Finseo API gives you programmatic access to your AI visibility tracking data.
# Finseo API
Track how your brand appears across ChatGPT, Claude, Perplexity and other AI platforms. The Finseo Customer API lets you retrieve visibility metrics, manage prompts, analyze competitors, and export data.
## Base URL
```
https://api.finseo.ai/v1
```
## Quick example
```bash cURL theme={"system"}
curl --request GET \
--url https://api.finseo.ai/v1/projects/YOUR_PROJECT_ID/metrics?timeframe=30d \
--header "Authorization: Bearer $FINSEO_API_KEY"
```
```python Python theme={"system"}
import requests
headers = {"Authorization": "Bearer YOUR_API_KEY"}
response = requests.get(
"https://api.finseo.ai/v1/projects/YOUR_PROJECT_ID/metrics",
headers=headers,
params={"timeframe": "30d"}
)
data = response.json()["data"]
print(f"Visibility Rate: {data['current']['visibilityRate']}%")
print(f"Mentions: {data['current']['mentions']}")
print(f"Change: {data['changes']['visibilityRateChange']:+.1f}%")
```
```javascript Node.js theme={"system"}
const response = await fetch(
"https://api.finseo.ai/v1/projects/YOUR_PROJECT_ID/metrics?timeframe=30d",
{ headers: { Authorization: "Bearer YOUR_API_KEY" } }
);
const { data } = await response.json();
console.log(`Visibility: ${data.current.visibilityRate}%`);
console.log(`Mentions: ${data.current.mentions}`);
```
**Response:**
```json theme={"system"}
{
"data": {
"current": {
"visible": 28,
"notVisible": 14,
"mentions": 156,
"visibilityRate": 66.67,
"position": 22.4,
"sentiment": 0.78
},
"previous": {
"visible": 22,
"visibilityRate": 52.38
},
"changes": {
"visibilityRateChange": 14.29,
"mentionsChange": 38
}
}
}
```
## Response format
All endpoints return a consistent JSON envelope:
| Field | Description |
| ------- | --------------------------------- |
| `data` | The response payload |
| `meta` | Pagination info (when applicable) |
| `error` | Error details (only on failure) |
## Error codes
| Code | Status | Description |
| ----------------------- | ------ | --------------------------------- |
| `UNAUTHORIZED` | 401 | Missing or invalid API key |
| `FORBIDDEN` | 403 | Insufficient scopes |
| `NOT_FOUND` | 404 | Resource not found |
| `VALIDATION_ERROR` | 400 | Invalid parameters |
| `RATE_LIMIT_EXCEEDED` | 429 | Too many requests |
| `PROJECT_ACCESS_DENIED` | 403 | API key can't access this project |
| `INTERNAL_ERROR` | 500 | Server error |
Add the right questions to monitor AI visibility
Configure where Finseo runs your prompts
Upload server logs and monitor AI crawler access
Measure visits, conversions, and revenue from AI platforms
Send form, CRM, and order attribution into Finseo
Connect forms, CRMs, analytics, and attribution sources
Extract real user prompts from Google and Bing query data
Analyze mentioned products, shopping listings, stores, and attributes
Track brand framing, criticism, awards, and aspect scores
Create and manage API keys
Request limits per plan
Explore all endpoints
Connect to Claude Desktop or Cursor
# Integrations
Source: https://docs.finseo.ai/integrations
Connect forms, CRMs, analytics tools, project management tools, and CMS platforms to Finseo.
# Integrations
Finseo connects to your CMS, analytics tools, reporting stack, project management tools and CRM so you can optimize content, measure AI-referred traffic, push tasks to your team, and prove revenue impact. Every connector below has its own setup guide; in the app you'll find them under **Integrations**.
## CMS & content
Let the Finseo agent edit and optimize your site content directly.
Edit posts, pages and Yoast/RankMath meta tags via the WordPress REST API.
Update CMS items, page SEO settings and inject JSON-LD structured data.
Edit CMS entries, inject schemas into the head and publish your site.
Track checkouts for attribution today; agent-driven SEO edits coming soon.
## Analytics
Measure AI-referred traffic and AI crawler activity.
Track AI-referred traffic, conversions and revenue from GA4.
Privacy-friendly AI traffic tracking with Piwik PRO analytics.
Search queries, pages, CTR and positions alongside AI visibility.
Monitor Bing performance for Copilot-driven AI traffic.
Stream AI crawler visits to Bot Analytics in near real-time — via Worker or Logpush.
## Reporting & data
Build client dashboards and white-label reports with the community connector.
Use your visibility data in Claude, ChatGPT and Cursor via the Model Context Protocol.
Programmatic REST access to every dashboard metric for your own stack.
## Project management
Export tasks from the Finseo Tasks module into your team's tools — manually or via automation rules.
## Attribution & CRM
Send the answer to "How did you find us?" into Finseo whenever a lead, form submission, booking, order or deal is created. See the [Attribution guide](/attribution) for the full setup — including the Finseo Snippet that piggybacks on your existing Google/Meta tracking.
## E-commerce & payments
Orders and payments arrive as conversions and merge with survey answers via order ID or email — revenue is attributed to the channel the customer named.
## Post-purchase surveys
Already running a survey? Keep it — Finseo imports its answers instead of showing a second popup.
## How attribution integrations work
Attribution integrations use one of two paths:
* A **project webhook URL** for forms and CRMs with native webhooks.
* The **Finseo API** for automation tools such as Zapier, Make, or n8n.
Webhook URLs look like this:
```text theme={"system"}
https://app.finseo.ai/api/attribution/webhook/PROJECT_ID?source=SOURCE&token=WEBHOOK_TOKEN
```
The `source` parameter helps Finseo choose the right parser. The `token` protects the endpoint — you can regenerate it in the connect dialog at any time.
### Recommended survey question
For form tools, add a question like **"How did you find us?"** with answer options such as ChatGPT, Perplexity, Claude, Google, Social media, Friend or colleague, Ads, Other. Finseo normalizes the answers into attribution channels automatically.
### Field mapping
If a tool sends fields with unusual names, send one test payload first — the connect dialog's live listener shows the incoming structure. Then map the fields to attribution answer, email, name, deal value, deal currency and form ID. Use rules when a source field needs translation, e.g. map `utm_source contains chatgpt` to `AI Search`.
### Testing checklist
* Send a test submission from the source tool.
* Confirm the response appears in **Attribution**.
* Confirm the channel category is correct, especially for AI sources.
* Add `dealValue` and `dealCurrency` if you want revenue reporting.
* Add a stable `respondentExternalId` such as order ID, lead ID, or deal ID.
# Connect Asana to Finseo for AI Search Attribution
Source: https://docs.finseo.ai/integrations/asana
Send Finseo tasks into your Asana projects with evidence and action steps attached.
# Asana
Connect Asana to send AI visibility tasks from the Finseo **Tasks** module into any Asana project. Each exported task includes the recommendation, the data evidence behind it, and concrete action steps as notes.
## What you can do
* Export any Finseo task into an Asana project with one click.
* Auto-export new tasks via automation rules (filtered by category and impact).
* Assign exported tasks to Asana members directly from Finseo.
## Get your Personal Access Token
1. Open the [Asana developer console](https://app.asana.com/0/my-apps) (My apps).
2. Under **Personal access tokens**, click **Create new token**.
3. Name the token, agree to the API terms, and copy the token — it is shown only once.
See Asana's [Personal Access Token docs](https://developers.asana.com/docs/personal-access-token) for details.
## Connect
1. In Finseo, open **Integrations → Asana → Connect**.
2. Paste the token and save.
## Export tasks
* On the **Tasks** page, open a task and use **Export → Asana**, then pick the target project.
* Optionally choose an Asana assignee.
## Automation rules
Under **Tasks → Automation**, create rules that push new Finseo tasks into Asana automatically — filtered by category and minimum impact, with an optional default assignee.
## Troubleshooting
Personal access tokens start with a digit followed by a slash (e.g. `1/...`). Copy the full value directly after creating it — Asana does not show it again later.
Finseo lists projects your Asana user is a member of. Join the project in Asana, then reopen the picker.
# Connect Attio to Finseo for AI Search Attribution
Source: https://docs.finseo.ai/integrations/attio
Sync attribution answers from Attio CRM records to Finseo via webhooks.
# Attio
Connect Attio to receive attribution data when records are created. Attio's native webhooks fire on record events and send structured JSON with all attributes — including custom fields like "How did you find us?". Finseo scans the payload for the attribution answer and normalizes it into a channel.
## Get your webhook URL
1. In Finseo, open **Integrations → Attio → Connect**.
2. Copy your personal webhook URL (contains your project ID, `?source=attio`, and a secret token):
```text theme={"system"}
https://app.finseo.ai/api/attribution/webhook/YOUR_PROJECT_ID?source=attio&token=•••
```
## Set up the Attio webhook
1. In Attio, go to **Settings → Developers** and open (or create) an integration.
2. Create a **webhook** inside the integration with your Finseo URL as the target.
3. Subscribe to the event **`record.created`** for your People or Deals object (add `record.updated` if the attribution field is filled later).
4. Save. Attio can send a **test event** to the target URL from the same page — use it to verify the connection.
If your People object doesn't have an attribution attribute yet, add a custom attribute like "How did you find us?" first.
See Attio's [webhook docs](https://docs.attio.com/rest-api/guides/webhooks) for details.
## Test and map fields
* Use the **live listener** in the Finseo connect dialog or Attio's "Send test event" feature and inspect the received payload.
* If the attribution attribute isn't detected automatically, select it under **Field Mapping**.
## Troubleshooting
Check that the webhook status in Attio is "active" and that the subscribed event matches how your records are created. Webhooks created via OAuth tokens are not visible in the developer settings page.
Attio sends all record attributes — use Field Mapping in Finseo to point at the attribute that holds the attribution answer.
# Connect Calendly to Finseo for AI Search Attribution
Source: https://docs.finseo.ai/integrations/calendly
Capture "How did you hear about us?" answers from Calendly booking forms in Finseo.
# Calendly
Connect Calendly to receive attribution data from booking form questions. When someone schedules a meeting, Calendly sends a webhook with all invitee answers — including your "How did you hear about us?" question — which Finseo normalizes into attribution channels.
## Requirements
* Calendly webhooks require a paid plan: **Standard**, **Teams**, or **Enterprise** (not available on Free).
* Webhook subscriptions are created via the Calendly API — there is no UI toggle. You need a [personal access token](https://calendly.com/integrations/api_webhooks) from your Calendly integrations page.
* An invitee question on your event type, e.g. "How did you hear about us?".
## Get your webhook URL
1. In Finseo, open **Integrations → Calendly → Connect**.
2. Copy your personal webhook URL (contains your project ID, `?source=calendly`, and a secret token):
```text theme={"system"}
https://app.finseo.ai/api/attribution/webhook/YOUR_PROJECT_ID?source=calendly&token=•••
```
## Create the webhook subscription
Create the subscription with one API call (replace the token and URLs):
```bash theme={"system"}
curl --request POST \
--url https://api.calendly.com/webhook_subscriptions \
--header "Authorization: Bearer $CALENDLY_ACCESS_TOKEN" \
--header 'Content-Type: application/json' \
--data '{
"url": "https://app.finseo.ai/api/attribution/webhook/YOUR_PROJECT_ID?source=calendly&token=YOUR_TOKEN",
"events": ["invitee.created"],
"organization": "https://api.calendly.com/organizations/YOUR_ORG_URI",
"scope": "organization"
}'
```
Use `"scope": "user"` with a `user` URI instead if you only want your own bookings. Finseo extracts the attribution answer from the `questions_and_answers` array automatically.
See Calendly's [webhook docs](https://developer.calendly.com/api-docs/d7755e2f9e5fe-webhooks) for details.
## Test and map fields
* Use the **live listener** in the Finseo connect dialog: book a test meeting and inspect the received payload.
* If your question is phrased differently, select the right answer under **Field Mapping**.
## Troubleshooting
Webhooks require a Standard plan or higher on the Calendly account that owns the token. Free accounts can read the API but cannot create webhook subscriptions.
Make sure the question is part of the event type's invitee questions (or a routing form) — answers only appear in the payload if the invitee actually saw the question.
# Connect ClickUp to Finseo for AI Search Attribution
Source: https://docs.finseo.ai/integrations/clickup
Export Finseo tasks into ClickUp lists and assign them to ClickUp members — manually or via automation rules.
# ClickUp
Connect ClickUp to push tasks from the Finseo **Tasks** module directly into your ClickUp lists. Each exported task arrives with its title, the data evidence behind it, and step-by-step instructions. Once connected, ClickUp workspace members also appear in Finseo's assignee dropdowns, marked with the ClickUp icon.
## What you can do
* Export any Finseo task into a ClickUp list with one click.
* Auto-export new tasks via automation rules (filtered by category and impact).
* Assign exported tasks to ClickUp members directly from Finseo.
## Get your API token
Finseo authenticates with your personal ClickUp API token:
1. Log in to ClickUp and click your avatar in the upper-right corner.
2. Select **Settings**, then click **Apps** in the sidebar.
3. Under **API Token**, click **Generate** (or **Regenerate**) and copy the token — it starts with `pk_`.
See ClickUp's [authentication docs](https://developer.clickup.com/docs/authentication) for details.
The token acts with your ClickUp permissions. Tasks are created in your name and can only target lists you can access.
## Connect
1. In Finseo, open **Integrations → ClickUp → Connect**.
2. Paste the token and save.
## Export tasks
* On the **Tasks** page, open a task and use **Export → ClickUp**, then pick the destination list (Space → Folder → List).
* Optionally choose a ClickUp assignee — the member list is loaded live from your workspace.
## Automation rules
Under **Tasks → Automation** you can create rules that run on every newly generated task:
1. Choose filters: category (Content, Technical, Authority, …) and minimum impact.
2. Enable **Create in PM tool → ClickUp** and select the target list.
3. Optionally set **Assign in ClickUp** to a member — new tasks are then created and assigned automatically.
## Troubleshooting
Make sure you copied the full personal token starting with `pk_` from Settings → Apps. OAuth app client secrets do not work here.
Finseo only shows lists your ClickUp user can access. Ask a ClickUp admin to share the Space or Folder with you, then reopen the picker.
# Connect Close to Finseo for AI Search Attribution
Source: https://docs.finseo.ai/integrations/close
Receive lead attribution from Close CRM webhooks in Finseo.
# Close
Connect Close CRM to capture attribution when leads are created. Close fires a webhook with the lead data including custom fields; Finseo scans for the "How did you find us?" answer and normalizes it into an attribution channel.
## Requirements
* Webhooks in the Close UI are available on the **Business** plan and higher. On lower plans you can create webhook subscriptions via the [Close API](https://developer.close.com/resources/webhook-subscriptions) instead.
* A custom field on leads that captures the attribution answer.
## Get your webhook URL
1. In Finseo, open **Integrations → Close → Connect**.
2. Copy your personal webhook URL (contains your project ID, `?source=close-crm`, and a secret token):
```text theme={"system"}
https://app.finseo.ai/api/attribution/webhook/YOUR_PROJECT_ID?source=close-crm&token=•••
```
## Set up the Close webhook
1. In Close, go to **Settings → Integrations → Webhooks** (gear icon in the bottom-left sidebar).
2. Click **Add Webhook** and paste your Finseo URL.
3. Select the event **`lead.created`** (add `lead.updated` if the attribution field is filled later).
4. Save — Close sends a test ping to verify the endpoint is reachable.
Alternatively via API: `POST https://api.close.com/api/v1/webhook/` with `url` and `events: [{"object_type": "lead", "action": "created"}]`.
## Test and map fields
* Use the **live listener** in the Finseo connect dialog: create a test lead in Close and inspect the received payload.
* If the attribution custom field isn't detected automatically, select it under **Field Mapping**.
## Troubleshooting
UI-managed webhooks require the Business plan. Either upgrade, create the subscription via the API, or route the data through Zapier/Make/n8n.
# Connect Custom Webhook to Finseo for AI Search Attribution
Source: https://docs.finseo.ai/integrations/custom-webhook
Send attribution data to Finseo from any source via the generic webhook endpoint.
# Custom Webhook
Use the generic webhook endpoint to send attribution data from any custom integration — your own backend, a form handler, or an internal tool. Finseo auto-detects known payload formats (HubSpot, Salesforce, Typeform, Jotform, …) and also accepts plain JSON.
## Get your webhook URL
1. In Finseo, open **Integrations → Custom Webhook → Connect**.
2. Copy your personal webhook URL (contains your project ID and a secret token):
```text theme={"system"}
https://app.finseo.ai/api/attribution/webhook/YOUR_PROJECT_ID?token=•••
```
## Send a request
POST JSON with at minimum a `channelId` (or a `freetextResponse` that Finseo categorizes):
```bash theme={"system"}
curl -X POST "https://app.finseo.ai/api/attribution/webhook/YOUR_PROJECT_ID?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"channelId": "ai_chatgpt",
"respondentEmail": "jane@example.com",
"respondentName": "Jane Doe",
"dealValue": 490,
"dealCurrency": "EUR",
"metadata": { "campaign": "spring-launch" }
}'
```
Supported fields: `channelId`, `channelLabel`, `channelCategory`, `subChannel`, `freetextResponse`, `respondentEmail`, `respondentName`, `respondentExternalId`, `dealValue`, `dealCurrency`, `pageUrl`, `formId`, `metadata`.
## Test and map fields
* The connect dialog has a **live listener**: turn it on, send a request, and Finseo shows the received payload with a parse result.
* For non-standard payloads, use **Field Mapping** to tell Finseo which field holds the attribution answer.
## Security
* The `token` query parameter authenticates requests — treat the URL like a secret. You can regenerate the token in the connect dialog at any time (the old URL stops working immediately).
* Optionally configure an outbound webhook in the Attribution settings to get notified about new responses in your own systems.
## Troubleshooting
Check that the URL includes the current `token` — after regenerating, old URLs are invalid. The body must be JSON (or form-encoded for known providers).
Send an explicit `channelId` instead of relying on freetext categorization, or adjust the Field Mapping.
# Connect Fairing to Finseo for AI Search Attribution
Source: https://docs.finseo.ai/integrations/fairing
Import Fairing post-purchase survey answers into Finseo attribution via Shopify Flow.
# Fairing
Already running a [Fairing](https://fairing.co) post-purchase survey on Shopify? Keep it — Finseo imports its answers instead of showing a second popup. Answers merge with the order automatically via order ID and email.
## Step 1: Connect Fairing to Shopify Flow
In the Fairing app, open **Integrations → Shopify Flow → Connect**. This step is required — Fairing only sends survey responses to Flow after the connection is made.
## Step 2: Build the Flow
1. In Shopify, go to **Flow → Create workflow**.
2. Trigger: **Fairing Post Purchase Surveys — New Survey Response**.
3. Action: **Send HTTP request** with:
```text theme={"system"}
Method: POST
Header: Content-Type: application/json
URL: https://app.finseo.ai/api/attribution/webhook/YOUR_PROJECT_ID?token=•••
```
4. Body:
```json theme={"system"}
{
"channel": "{{trigger.response}}",
"freetext": "{{trigger.responseWasOther}}",
"question": "{{trigger.question}}",
"respondentExternalId": "{{order.id}}",
"respondentEmail": "{{order.email}}"
}
```
5. Turn the workflow on.
Finseo normalizes the answer text into channels automatically — "Saw you on ChatGPT" becomes `ai_search`. The order ID and email merge the answer with the checkout conversion from your [Shopify Custom Pixel](/integrations/shopify#track-checkouts-for-attribution).
## Troubleshooting
The Flow connection in the Fairing app hasn't been made yet — open Fairing → Integrations → Shopify Flow → Connect first.
Revenue comes from the checkout conversion, not the survey. Install the Shopify Custom Pixel so orders arrive with value — they merge with the Fairing answer via order ID.
# Connect Formstack to Finseo for AI Search Attribution
Source: https://docs.finseo.ai/integrations/formstack
Receive Formstack form submissions in Finseo for attribution tracking.
# Formstack
Connect Formstack to send form submissions to Finseo for attribution tracking. Formstack's native webhooks POST JSON payloads with the form field data on every submission.
## Get your webhook URL
1. In Finseo, open **Integrations → Formstack → Connect**.
2. Copy your personal webhook URL (contains your project ID, `?source=formstack`, and a secret token):
```text theme={"system"}
https://app.finseo.ai/api/attribution/webhook/YOUR_PROJECT_ID?source=formstack&token=•••
```
## Set up the Formstack webhook
1. In Formstack, open your form and go to **Settings → Integrations → Webhooks**.
2. Add your Finseo webhook URL as the endpoint.
3. Choose to send the data as JSON with field labels if available, then save.
See Formstack's [webhook help article](https://help.formstack.com/s/article/Webhook-integration) for details.
## Test and map fields
* Use the **live listener** in the Finseo connect dialog: submit a test entry and inspect the received payload.
* Formstack maps field IDs to values — select your "How did you find us?" field under **Field Mapping** in the dialog.
## Troubleshooting
Confirm the webhook is active on the specific form (webhooks are configured per form, not account-wide) and the URL includes `source` and `token` parameters.
Use Field Mapping once to select the right field — Finseo remembers the mapping for all future submissions.
# Connect Framer to Finseo for AEO & GEO
Source: https://docs.finseo.ai/integrations/framer
Let the Finseo agent optimize your Framer pages and CMS content via the Server API.
# Framer
Connect your Framer site to let the agent optimize CMS entries, inject JSON-LD schemas into the site head, and publish changes — all from the chat. The integration uses Framer's Server API.
## What the agent can do
* Edit CMS collection items.
* Inject custom code (e.g. JSON-LD structured data) into head/body.
* Publish and deploy your site programmatically.
## Generate an API key
Framer Server API keys are created per project:
1. Open your project in Framer and go to **Site Settings** (Cmd+K → "open settings").
2. Find the **API Keys** section under General.
3. Create a key and copy it — store it securely.
The Server API is currently in open beta at Framer; keys authenticate as the user who created them and are bound to one project.
## Connect
1. In Finseo, open **Integrations → Framer → Connect**.
2. Enter your Framer project URL and the API key.
3. Save — then open the **Agent** and start optimizing, e.g. "Inject Organization schema into my site head and publish".
## Safety
* Every edit requires your confirmation before it is applied.
* Publishing/deploying is an explicit step the agent announces beforehand.
## Troubleshooting
Keys are project-bound — the project URL and the API key must belong to the same Framer project. Regenerate the key in Site Settings if in doubt.
# Connect Google Analytics (GA4) to Finseo
Source: https://docs.finseo.ai/integrations/google-analytics
Track AI-referred traffic, conversions and revenue by connecting GA4 to Finseo.
# Google Analytics (GA4)
Connect Google Analytics 4 to see exactly how much traffic AI platforms send to your site. Finseo identifies sessions referred by ChatGPT, Perplexity, Claude, Gemini, Copilot and other AI platforms in your GA4 data and shows trends, landing pages, conversions and revenue in the **AI Analytics** dashboard.
## What you get
* **AI traffic trend** — daily sessions referred by AI platforms, split per platform.
* **Top AI landing pages** — which pages AI visitors land on.
* **Conversions & revenue** — your GA4 conversion events and purchase revenue attributed to AI traffic.
* **Comparison** — AI traffic share vs. organic and other channels.
## Requirements
* A GA4 property with your website's data (Universal Analytics is not supported).
* A Google account with at least **Viewer** access to that property.
## Connect
1. In Finseo, open **Integrations → Google Analytics → Connect** (or go directly to the **AI Analytics** page).
2. Sign in with Google and approve read access — Finseo only requests read-only Analytics scopes.
3. Select the GA4 property (and data stream) for your project.
4. Done — the AI Analytics page fills with data. Historical data is available as far back as your GA4 property retains it.
## How AI traffic is detected
Finseo classifies sessions by referrer and source/medium: referrals from domains like `chatgpt.com`, `perplexity.ai`, `gemini.google.com`, `copilot.microsoft.com`, and campaign parameters that identify AI platforms. No tagging or code change on your site is required.
## Troubleshooting
Your Google account has no GA4 access. Ask the property admin for at least Viewer access, then reconnect.
Some AI platforms open links without a referrer (dark traffic). Finseo shows what's identifiable in GA4 — combining this with [Bot Analytics](/bot-analytics) and [Attribution](/attribution) gives the fuller picture.
Mark the relevant events as key events (conversions) in GA4 — Finseo reads the conversion events your property defines.
# Connect Gravity Forms to Finseo for AI Search Attribution
Source: https://docs.finseo.ai/integrations/gravity-forms
Send WordPress Gravity Forms submissions to Finseo attribution via the Webhooks Add-On.
# Gravity Forms
Connect Gravity Forms (WordPress) to send form submissions to Finseo for attribution tracking. The Gravity Forms **Webhooks Add-On** POSTs each entry as JSON to your Finseo webhook URL.
## Requirements
* The Webhooks Add-On requires a Gravity Forms **Elite** (or Nonprofit) license — it is not included in Basic or Pro. Upgrades are prorated.
* A form field that captures the attribution answer (e.g. "How did you find us?").
## Get your webhook URL
1. In Finseo, open **Integrations → Gravity Forms → Connect**.
2. Copy your personal webhook URL (contains your project ID, `?source=gravity-forms`, and a secret token):
```text theme={"system"}
https://app.finseo.ai/api/attribution/webhook/YOUR_PROJECT_ID?source=gravity-forms&token=•••
```
## Set up the webhook feed
1. In WordPress, go to **Forms → Add-Ons**, install and activate the **Webhooks Add-On**.
2. Edit your form → **Settings → Webhooks → Add New**.
3. Configure the feed:
* **Request URL**: your Finseo webhook URL
* **Request Method**: `POST`
* **Request Format**: `JSON`
* **Request Body**: All fields (or select the relevant ones)
4. Save the feed.
See the [Gravity Forms webhooks docs](https://docs.gravityforms.com/category/add-ons-gravity-forms/webhooks-add-on/) for details.
## Test and map fields
* Use the **live listener** in the Finseo connect dialog: submit a test entry and inspect the received payload.
* Gravity Forms sends fields under numeric IDs or labels — select your attribution field under **Field Mapping** in the dialog.
## Troubleshooting
Your license doesn't include it — the add-on requires an Elite or Nonprofit license. Alternatively, route submissions through Zapier, Make, or n8n.
Some security plugins block outgoing requests. Whitelist `app.finseo.ai` or check the webhook feed's logs under Forms → Settings → Logging.
# Connect HubSpot to Finseo for AI Search Attribution
Source: https://docs.finseo.ai/integrations/hubspot
Send "How did you hear about us?" answers from HubSpot workflows to Finseo attribution.
# HubSpot
Connect HubSpot to automatically feed attribution survey responses into Finseo. When a lead submits a form with a "How did you hear about us?" field, a HubSpot workflow sends the contact to Finseo via webhook. Finseo normalizes the answer into attribution channels (ChatGPT, Perplexity, Google, referral, …) and correlates it with your AI visibility data.
## Requirements
* A HubSpot subscription that includes the **Send a webhook** workflow action — Operations Hub **Professional/Enterprise** or Data Hub **Professional/Enterprise**. It is not included in standard Marketing/Sales/Service Hub Professional tiers.
* A form (or property) that captures the attribution answer, e.g. a "How did you hear about us?" field.
## Get your webhook URL
1. In Finseo, open **Integrations → HubSpot → Connect**.
2. Copy your personal webhook URL. It already contains your project ID, the `?source=hubspot` marker for automatic payload detection, and a secret token:
```text theme={"system"}
https://app.finseo.ai/api/attribution/webhook/YOUR_PROJECT_ID?source=hubspot&token=•••
```
## Set up the HubSpot workflow
1. In HubSpot, go to **Automations → Workflows → Create workflow** (contact-based).
2. Set the enrollment trigger to **Form submission** on your signup or contact form.
3. Add the action **Send a webhook** (in the Data ops section), method **POST**.
4. Paste your Finseo webhook URL.
5. Include the contact properties in the request body — at minimum email, name, and your attribution field.
6. Turn the workflow on.
Finseo automatically parses HubSpot contact payloads and extracts email, name, and the attribution answer.
## Test and map fields
* The Finseo connect dialog has a **live listener**: turn it on, trigger a test enrollment in HubSpot, and Finseo shows the received payload.
* If the attribution answer is not detected automatically, use **Field Mapping** in the dialog to point Finseo at the right property.
## Troubleshooting
Your HubSpot subscription doesn't include the webhook action (it requires Operations Hub or Data Hub Professional/Enterprise). As a workaround, route the form through Zapier, Make, or n8n instead — see the [Zapier / Make integration](/integrations/zapier-make).
Finseo scans field names for keywords like "how did", "find us", "source", "referral". If your property is named differently, set it explicitly under Field Mapping.
# Connect Intercom to Finseo for AI Search Attribution
Source: https://docs.finseo.ai/integrations/intercom
Capture attribution from Intercom contact events in Finseo.
# Intercom
Connect Intercom to receive attribution data when contacts are created. An Intercom webhook sends the contact's attributes — including a "How did you find us?" custom attribute — to Finseo, which normalizes the answer into an attribution channel.
## Requirements
* Intercom webhooks are configured through a **Developer Hub app** (a free internal app for your workspace).
* A custom attribute on contacts that captures the attribution answer.
## Get your webhook URL
1. In Finseo, open **Integrations → Intercom → Connect**.
2. Copy your personal webhook URL (contains your project ID, `?source=intercom`, and a secret token):
```text theme={"system"}
https://app.finseo.ai/api/attribution/webhook/YOUR_PROJECT_ID?source=intercom&token=•••
```
## Set up the Intercom webhook
1. Open the [Intercom Developer Hub](https://app.intercom.com/a/apps/_/developer-hub) and create an internal app (or open an existing one).
2. Under **Configure → Webhooks**, paste your Finseo URL as the endpoint. Intercom validates the URL with a HEAD request.
3. Subscribe to topics such as **`contact.user.created`** and **`contact.lead.created`** (add `conversation.admin.closed` if you capture the answer in conversations).
4. On the app's **Authentication** page, enable the permission scopes the topics require (e.g. "Read and write users") — without them the webhook won't fire.
5. Save.
See Intercom's [webhook setup guide](https://developers.intercom.com/docs/webhooks/setting-up-webhooks) for details.
## Test and map fields
* Use the **live listener** in the Finseo connect dialog: create a test contact and inspect the received payload.
* Select your attribution custom attribute under **Field Mapping** if it isn't detected automatically.
## Troubleshooting
Check that the topic's required permission scopes are enabled on the app's Authentication page — topics without matching scopes are silently skipped.
The available topics depend on the API version your app uses. Update the app's API version in the Developer Hub if needed.
# Connect Jira to Finseo for AI Search Attribution
Source: https://docs.finseo.ai/integrations/jira
Export Finseo tasks as Jira Cloud issues with formatted descriptions.
# Jira
Connect Jira Cloud to export Finseo tasks as Jira issues into any project. Descriptions arrive fully formatted with the data evidence and step-by-step instructions.
## What you can do
* Export any Finseo task as a Jira issue with one click.
* Auto-export new tasks via automation rules (filtered by category and impact).
* Assign exported issues to Jira users directly from Finseo.
## Get your API token
Finseo authenticates with Basic auth: your Atlassian account email plus an API token.
1. Go to [id.atlassian.com → Security → API tokens](https://id.atlassian.com/manage-profile/security/api-tokens).
2. Click **Create API token**, name it, and copy the value.
See Atlassian's [API token docs](https://support.atlassian.com/atlassian-account/docs/manage-api-tokens-for-your-atlassian-account/) for details.
## Connect
1. In Finseo, open **Integrations → Jira → Connect**.
2. Enter your site URL (`your-team.atlassian.net`), your account email, and the API token.
3. Save.
## Export tasks
* On the **Tasks** page, open a task and use **Export → Jira**, then pick the target project.
* Optionally choose a Jira assignee.
## Automation rules
Under **Tasks → Automation**, create rules that push new Finseo tasks into Jira automatically — filtered by category and minimum impact, with an optional default assignee.
## Troubleshooting
Use the email address of the Atlassian account that created the token, and the bare site domain without `https://` (e.g. `acme.atlassian.net`). Tokens created for a different Atlassian site will not work.
Finseo lists projects your Jira user can create issues in. Check your project permissions in Jira, then reopen the picker.
# Connect Jotform to Finseo for AI Search Attribution
Source: https://docs.finseo.ai/integrations/jotform
Receive Jotform survey submissions in Finseo for attribution tracking.
# Jotform
Connect Jotform to automatically receive "How did you find us?" survey responses. Jotform's native webhook sends every submission to Finseo, which auto-detects the attribution field.
## Get your webhook URL
1. In Finseo, open **Integrations → Jotform → Connect**.
2. Copy your personal webhook URL (contains your project ID, `?source=jotform`, and a secret token):
```text theme={"system"}
https://app.finseo.ai/api/attribution/webhook/YOUR_PROJECT_ID?source=jotform&token=•••
```
## Set up the Jotform webhook
1. In Jotform, open your form and go to **Settings → Integrations**.
2. Search for **Webhooks** and add your Finseo URL.
3. Complete the integration — every new submission is now forwarded.
Jotform sends form data as `multipart/form-data` with a `rawRequest` JSON field. Finseo handles both formats automatically and scans field names for attribution keywords (`how_did`, `find_us`, `source`, `referral`).
See Jotform's [webhook guide](https://www.jotform.com/help/245-how-to-setup-webhook-with-jotform) for details.
## Test and map fields
* Use the **live listener** in the Finseo connect dialog: submit a test entry and inspect the received payload.
* If your field is named differently, select it under **Field Mapping** in the dialog.
## Troubleshooting
Verify the webhook is listed under Settings → Integrations and the URL contains the full query string. Jotform retries failed deliveries only briefly.
Jotform field keys are auto-generated (e.g. `q12_howDid`). Use Field Mapping to select the right field once — Finseo remembers it for all future submissions.
# Connect KnoCommerce to Finseo for AI Search Attribution
Source: https://docs.finseo.ai/integrations/knocommerce
Import KnoCommerce post-purchase survey answers into Finseo attribution via webhook.
# KnoCommerce
Already running a [KnoCommerce](https://knocommerce.com) post-purchase survey (Shopify or WooCommerce)? Keep it — Finseo imports its answers instead of showing a second popup. Register a webhook via the KnoCommerce API and Finseo parses the payload automatically, merging answers with orders via ID and email.
## Set up the webhook
1. In KnoCommerce, go to **Settings → API Access** and create API credentials.
2. Register a webhook via their REST API:
```text theme={"system"}
Topic: response/create
URL: https://app.finseo.ai/api/attribution/webhook/YOUR_PROJECT_ID?token=•••
```
The KnoCommerce docs ([docs.knocommerce.com](https://docs.knocommerce.com)) show the exact webhook-creation request under their "Make Integration" guide.
## Field mapping
Finseo detects the answer, email, and order fields in KnoCommerce payloads automatically. If your survey uses a custom question structure, send one test response and map the fields once in **Attribution → Workflows** — future responses with the same structure parse automatically.
## Troubleshooting
Finseo normalizes answer text by keywords (chatgpt, google, instagram, …). If your answer options use unusual wording, add rules in the workflow's field mapping to translate them to channels.
Verify the webhook registration via the KnoCommerce API (list webhooks) and check that the URL contains your token — check **Attribution → Webhook logs** in Finseo for rejected requests.
# Connect Linear to Finseo for AI Search Attribution
Source: https://docs.finseo.ai/integrations/linear
Turn Finseo visibility tasks into Linear issues with full markdown descriptions.
# Linear
Connect Linear to turn Finseo tasks into Linear issues — including the full markdown description with evidence and recommended steps. Ideal for engineering-driven teams handling technical GEO fixes such as crawlability or structured-data work.
## What you can do
* Export any Finseo task as a Linear issue with one click.
* Auto-export new tasks via automation rules (filtered by category and impact).
* Assign exported issues to Linear members directly from Finseo.
## Get your API key
1. In Linear, open **Settings → Security & access**.
2. Under **Personal API keys**, click **New API key**.
3. Name the key and copy it — it starts with `lin_api_`.
See Linear's [API key docs](https://developers.linear.app/docs/graphql/working-with-the-graphql-api#personal-api-keys) for details.
## Connect
1. In Finseo, open **Integrations → Linear → Connect**.
2. Paste the key and save.
## Export tasks
* On the **Tasks** page, open a task and use **Export → Linear**, then pick the target team.
* Optionally choose a Linear assignee.
## Automation rules
Under **Tasks → Automation**, create rules that turn new Finseo tasks into Linear issues automatically — for example every task in the **Technical** category with high impact goes straight to your engineering team.
## Troubleshooting
Personal API keys start with `lin_api_`. OAuth tokens from Linear apps are not supported here.
Finseo lists teams your Linear user belongs to. Join the team in Linear, then reopen the picker.
# Connect Monday.com to Finseo for AI Search Attribution
Source: https://docs.finseo.ai/integrations/monday
Push Finseo visibility tasks onto your Monday boards as items.
# Monday.com
Connect Monday.com to create items on your boards from Finseo tasks. The task details, evidence and steps are attached as an update on each item.
## What you can do
* Export any Finseo task onto a Monday board with one click.
* Auto-export new tasks via automation rules (filtered by category and impact).
* Assign exported items to Monday members directly from Finseo.
## Get your API token
1. In Monday, click your avatar in the top-right corner.
2. Select **Developers** — the developer center opens.
3. Go to **My access tokens** and copy your personal token.
See Monday's [authentication docs](https://developer.monday.com/api-reference/docs/authentication) for details.
## Connect
1. In Finseo, open **Integrations → Monday.com → Connect**.
2. Paste the token and save.
## Export tasks
* On the **Tasks** page, open a task and use **Export → Monday**, then pick the target board.
* Optionally choose a Monday assignee.
## Automation rules
Under **Tasks → Automation**, create rules that push new Finseo tasks onto a Monday board automatically — filtered by category and minimum impact, with an optional default assignee.
## Troubleshooting
Copy the token from the developer center (avatar → Developers → My access tokens). App-specific OAuth tokens are not supported here.
Finseo lists boards your Monday user can access. Ask a board owner to invite you, then reopen the picker.
# Connect n8n to Finseo for AI Search Attribution
Source: https://docs.finseo.ai/integrations/n8n
Build custom attribution workflows into Finseo with the open-source automation tool n8n.
# n8n
Connect n8n to build custom attribution workflows. n8n is an open-source alternative to Zapier/Make — self-hosted or cloud — that can pipe any form, CRM, or data source into Finseo via an HTTP Request node, with full control over data transformation.
## What you need
* A Finseo API key with **write** scope: create it under **Settings → API → Create Key**.
* Your project ID (visible in the connect dialog under **Integrations → n8n**, or via `GET /v1/projects`).
## Set up the workflow
1. In n8n, create a new workflow with your preferred **trigger** (form submission, CRM event, webhook, schedule, …).
2. Add an **HTTP Request** node:
* **Method**: `POST`
* **URL**: `https://api.finseo.ai/v1/projects/YOUR_PROJECT_ID/attribution`
* **Authentication**: Generic → Header Auth with `Authorization: Bearer YOUR_API_KEY`
* **Body Content Type**: JSON
3. Map the fields:
```json theme={"system"}
{
"channelId": "ai_perplexity",
"freetextResponse": "={{ $json.how_did_you_find_us }}",
"respondentEmail": "={{ $json.email }}",
"dealValue": 1200,
"dealCurrency": "USD"
}
```
`channelId` is required — pass a fixed channel or forward the raw answer as `freetextResponse` and let Finseo categorize it. Optional fields: `channelLabel`, `subChannel`, `respondentName`, `pageUrl`, `formId`, `metadata`.
4. Execute the node once to test, then activate the workflow.
Alternatively, you can POST to your project's **webhook URL** (from the connect dialog) instead of the v1 API — useful if you'd rather not manage API keys in n8n.
## Troubleshooting
Check the Header Auth configuration: the header name must be `Authorization` and the value `Bearer YOUR_API_KEY` with write scope.
If you send `freetextResponse` without a matching `channelId`, Finseo categorizes the text automatically — check the raw answer text if categorization looks off.
# Connect Notion to Finseo for AI Search Attribution
Source: https://docs.finseo.ai/integrations/notion
Add Finseo visibility tasks as pages to any Notion database.
# Notion
Connect Notion to add Finseo tasks as pages in any Notion database — for example your content calendar or sprint board. The task description, evidence and steps land as page content.
## What you can do
* Export any Finseo task as a page into a Notion database.
* Auto-export new tasks via automation rules (filtered by category and impact).
## Create an internal integration
Notion uses an internal integration with a secret token:
1. Go to [notion.so/my-integrations](https://www.notion.so/my-integrations) (you must be a workspace owner) and click **New integration**.
2. Name it (e.g. "Finseo"), pick the workspace, and save.
3. On the configuration page, copy the **Internal Integration Secret** — it starts with `ntn_`.
## Share your database with the integration
This step is required. A new integration cannot see any content until you explicitly connect it to the target database — otherwise every export fails with "Could not find object".
1. Open the target database in Notion.
2. Click the **•••** menu in the top-right corner.
3. Choose **Connections** (or **Add connections**) and select your integration.
See Notion's [authorization docs](https://developers.notion.com/docs/authorization#internal-integration-auth-flow-set-up) for details.
## Connect
1. In Finseo, open **Integrations → Notion → Connect**.
2. Paste the secret and save.
## Export tasks
* On the **Tasks** page, open a task and use **Export → Notion**, then pick the target database. Finseo creates one page per task with the title as the page name and the full recommendation as page content.
## Automation rules
Under **Tasks → Automation**, create rules that add new Finseo tasks to a Notion database automatically — filtered by category and minimum impact.
## Troubleshooting
The integration has not been connected to the database. Open the database → ••• → Connections → add your integration, then try again.
Copy the Internal Integration Secret (starts with `ntn_`, older tokens with `secret_`) from the integration's configuration page — not the OAuth client secret of a public integration.
# Connect Pipedrive to Finseo for AI Search Attribution
Source: https://docs.finseo.ai/integrations/pipedrive
Capture deal attribution from Pipedrive Automations in Finseo.
# Pipedrive
Connect Pipedrive to receive attribution data when deals are created or updated. A Pipedrive Automation sends a webhook with deal and person fields to Finseo, which parses your "How did you find us?" custom field and maps it to an attribution channel.
## Requirements
* Webhook actions inside Automations require a Pipedrive **Advanced** plan or higher.
* A custom field on deals or persons that captures the attribution answer (e.g. "How did you find us?").
## Get your webhook URL
1. In Finseo, open **Integrations → Pipedrive → Connect**.
2. Copy your personal webhook URL (contains your project ID, `?source=pipedrive`, and a secret token):
```text theme={"system"}
https://app.finseo.ai/api/attribution/webhook/YOUR_PROJECT_ID?source=pipedrive&token=•••
```
## Set up the Pipedrive automation
1. In Pipedrive, first register the webhook: add your Finseo URL under the webhook settings so it becomes selectable in Automations.
2. Go to **Tools and apps → Automations → + Automation**.
3. Trigger: **Deal created** (or **Deal updated**, optionally monitoring your attribution field).
4. Action: **Send webhook** → select your Finseo webhook, method **POST**.
5. In the body (key-value or raw JSON), map the deal title, person email/name, deal value, and your attribution custom field.
6. Activate the automation.
## Test and map fields
* Use the **live listener** in the Finseo connect dialog: create a test deal and inspect the received payload.
* Pipedrive sends custom fields under hash-like keys — use **Field Mapping** in the dialog to select the attribution field if it isn't detected automatically.
## Troubleshooting
Webhook requests in Automations are available on Advanced plans and higher. On lower plans, route the data through Zapier, Make, or n8n instead — see [Zapier / Make](/integrations/zapier-make).
Include the deal's value and currency fields in the webhook body so Finseo can track revenue per attribution channel.
# Connect Piwik PRO to Finseo for AI Traffic Tracking
Source: https://docs.finseo.ai/integrations/piwik-pro
Track AI-referred traffic in Finseo with your Piwik PRO analytics data.
# Piwik PRO
Connect Piwik PRO as a privacy-friendly alternative to Google Analytics. Finseo reads your Piwik PRO session data to identify traffic referred by AI platforms (ChatGPT, Perplexity, Claude, Gemini, Copilot, …) and shows it in the **AI Analytics** dashboard.
## What you get
* **AI traffic trend** — daily sessions referred by AI platforms, split per platform.
* **Top AI landing pages** — which pages AI visitors land on.
* **Channel comparison** — AI traffic share alongside your other channels.
## Create API credentials
Finseo authenticates with Piwik PRO API credentials (OAuth client credentials):
1. Log in to Piwik PRO and click **Menu → your email address** (your profile).
2. Open the **API keys** tab and click **Create a key**.
3. Name the key and click **OK**.
4. Copy the **Client ID** and **Client secret** immediately — the secret is not shown again after you close the window.
See the [Piwik PRO help article](https://help.piwik.pro/support/questions/generate-api-credentials/) for details.
## Connect
1. In Finseo, open the **AI Analytics** page and choose **Connect → Piwik PRO** (also reachable via **Integrations**).
2. Enter your **account URL** (e.g. `yourcompany.piwik.pro`), the **Client ID**, and the **Client secret**.
3. Finseo validates the credentials and lists your sites — select the site to track.
4. Done — AI traffic data appears in the dashboard.
## Troubleshooting
Check the account URL format (no `https://`, just `yourcompany.piwik.pro`) and that the credentials were copied completely. Deleted API keys stop working immediately.
The API key inherits your user's permissions. Make sure your Piwik PRO user has access to the site you want to connect.
# Connect Salesforce to Finseo for AI Search Attribution
Source: https://docs.finseo.ai/integrations/salesforce
Send LeadSource and attribution data from Salesforce Flows to Finseo.
# Salesforce
Connect Salesforce to capture attribution when Leads or Contacts are created. A Record-Triggered Flow with an HTTP Callout POSTs the record to Finseo, which parses the `LeadSource` (or a custom attribution field) and normalizes it into attribution channels.
Salesforce's native **Outbound Messages** send XML and are not supported. Use a Flow with an **HTTP Callout** action instead — no Apex code required.
## Get your webhook URL
1. In Finseo, open **Integrations → Salesforce → Connect**.
2. Copy your personal webhook URL (contains your project ID, `?source=salesforce`, and a secret token):
```text theme={"system"}
https://app.finseo.ai/api/attribution/webhook/YOUR_PROJECT_ID?source=salesforce&token=•••
```
## Set up the Salesforce Flow
1. In **Setup → Flow Builder**, create a **Record-Triggered Flow**.
2. Object: **Lead** (or Contact), trigger: **A record is created**.
3. Create a **Named Credential** for `https://app.finseo.ai` (required for HTTP Callouts).
4. Add an **HTTP Callout** action: method **POST**, path `/api/attribution/webhook/YOUR_PROJECT_ID?source=salesforce&token=...`.
5. Build the JSON body from record fields — map at minimum `LeadSource`, `Email`, `Name`, and optionally an `Amount` for deal value.
6. Activate the Flow.
## Test and map fields
* Use the **live listener** in the Finseo connect dialog: create a test Lead and inspect the received payload.
* If the attribution value sits in a custom field instead of `LeadSource`, point Finseo at it via **Field Mapping**.
## Troubleshooting
Check that the Named Credential points to `https://app.finseo.ai` and that the callout path includes the full query string with `source` and `token`.
Finseo maps common LeadSource values (e.g. "ChatGPT", "Google", "Referral") automatically. For custom picklist values, use Field Mapping or adjust the picklist labels.
# Connect Shopify to Finseo for AI Search Attribution
Source: https://docs.finseo.ai/integrations/shopify
Track checkouts for attribution with a Custom Pixel, and optimize your store's AEO & GEO with the Finseo agent (coming soon).
# Shopify
## Track checkouts for attribution
Available today: a Shopify **Custom Pixel** that sends every completed checkout (order ID, value, currency, customer email) to Finseo [attribution](/attribution). Theme scripts don't run on Shopify's checkout — this pixel does. Orders merge with "How did you hear about us?" answers via order ID or email.
### Install the pixel
1. In Shopify, go to **Admin → Settings → Customer events → Add custom pixel**.
2. Paste the pixel code (get your personal version with project ID and token from **Attribution → Set up attribution → Shopify** in Finseo):
```js theme={"system"}
const WEBHOOK_URL = 'https://app.finseo.ai/api/attribution/webhook/YOUR_PROJECT_ID?token=•••';
analytics.subscribe('checkout_completed', (event) => {
const checkout = event.data.checkout;
if (init.customerPrivacy &&
init.customerPrivacy.analyticsProcessingAllowed === false) return;
fetch(WEBHOOK_URL, {
method: 'POST',
headers: { 'Content-Type': 'application/json' },
body: JSON.stringify({
respondentExternalId: String((checkout.order && checkout.order.id) || checkout.token),
dealValue: Number(checkout.totalPrice ? checkout.totalPrice.amount : 0),
dealCurrency: checkout.totalPrice ? checkout.totalPrice.currencyCode : 'USD',
respondentEmail: checkout.email || undefined
}),
keepalive: true
});
});
```
3. Save and **connect** the pixel.
4. Customer privacy settings: Permission **Required** with only **Analytics** checked · Data sale: **not considered data sale**. The pixel respects the customer's consent — checkouts without analytics permission are not sent.
### Where does the survey go?
Shopify's checkout and thank-you page are sandboxed — external scripts (including the Finseo popup) can't run there. Two options:
* **Survey app (best data)**: use [Fairing](/integrations/fairing), [KnoCommerce](/integrations/knocommerce), or [Zigpoll](/integrations/zigpoll) for a native post-purchase survey — Finseo imports the answers automatically.
* **Storefront popup**: add the [Finseo Snippet](/attribution#the-finseo-snippet) to your theme (**Online Store → Themes → Edit code → `theme.liquid`** before `