Dashboard VayaPin
9 endpoints from the published OpenAPI import.
Get Vayapin Stats
Get VayaPin dashboard KPI statistics.
Honors only the SCOPE filters (search / country / campaign / date range) — status + has_seo are deliberately ignored here because these KPIs ARE the status/SEO breakdown (Total / With-SEO / Success-rate).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
search | query | any | false | |
country | query | any | false | |
campaign_id | query | any | false | |
date_from | query | any | false | |
date_to | query | any | false |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/vayapin/stats' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/vayapin/stats",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/vayapin/stats", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/vayapin/stats", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Get Vayapin Funnel
Conversion funnel: businesses → with-email → pin-created → SEO-enriched.
Honors only the SCOPE filters (search / country / campaign / date range) — like /stats, it deliberately ignores status / has_seo / reason because the funnel IS that breakdown. Computed in a single pass via COUNT(*) FILTER over all rows in scope (NOT gated on vayapin_status IS NOT NULL), so businesses that never reached the pin stage are counted in businesses_total.
Monotonicity (F.5, Option A). Every step is a genuine subset of the one above, so the chart shrinks left→right and never inverts:
with_email= the SAME gate pin-creation uses (module f:skip = not best_email, where best_email = a verified-domain-matched email OR any found site email). So a row counts ifemails_foundORemails_verifiedis a non-empty array — OR the row already produced a pin (vayapin_status='exported'), because a created pin is proof-positive that the gate passed even on the ~755 older rows whose email arrays were never persisted back to CWJ. This makespin_createda true subset ofwith_email.seo_enrichedis gated onvayapin_status='exported'too, so a pin whose PATCH failed but whose SEO markdown was generated cannot inflate the SEO step abovepin_created.
Pin-creation behavior is UNCHANGED — this is a display/definition change only. A secondary with_verified_email count (verified array non-empty) is returned for insight but is NOT part of the monotonic chain.
VC.3 — the response additionally carries metrics (the eleven VayaCore contract fields plus one reconciliation aid, each RAW/unclamped and either valued or unavailable-with-a-reason) and window (the half-open UTC instant range actually queried). Everything above is untouched: the dashboard keeps its clamped chain, and no clamped field is ever substituted for a raw one.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
search | query | any | false | |
country | query | any | false | |
campaign_id | query | any | false | |
date_from | query | any | false | |
date_to | query | any | false |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/vayapin/funnel' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/vayapin/funnel",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/vayapin/funnel", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/vayapin/funnel", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Get Vayapin Reasons
Reason breakdowns behind the funnel drops.
fail_reasons = GROUP BY vayapin_fail_reason (why no pin — populated forward by the 2.1 callback). seo_reasons = GROUP BY vayapin_seo_reason (why no SEO content). Only non-null reasons returned, most-frequent first; served by the mig-379 partial indexes. Honors the SCOPE filters only (like /stats).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
search | query | any | false | |
country | query | any | false | |
campaign_id | query | any | false | |
date_from | query | any | false | |
date_to | query | any | false |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/vayapin/reasons' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/vayapin/reasons",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/vayapin/reasons", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/vayapin/reasons", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Get Vayapin Pins
Get paginated list of VayaPin rows with search and filters.
Shows ALL businesses that reached the VayaPin stage — including failed and never-reached (vayapin_status NULL) rows — so the dashboard can surface WHY a lead got no pin (previously these were hidden by a vayapin_status IS NOT NULL gate). Use status=exported to narrow to created pins.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
page | query | integer | false | |
page_size | query | integer | false | |
search | query | any | false | |
country | query | any | false | |
status | query | any | false | |
has_seo | query | any | false | |
reason | query | any | false | Filter to rows whose fail_reason OR seo_reason matches |
campaign_id | query | any | false | |
date_from | query | any | false | Filter PINs exported on/after this date (YYYY-MM-DD) |
date_to | query | any | false | Filter PINs exported on/before this date (YYYY-MM-DD) |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/vayapin/pins' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/vayapin/pins",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/vayapin/pins", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/vayapin/pins", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Get Vayapin Pin Detail
Get full PIN detail including SEO content and API audit log.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
cwj_id | path | integer | true |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/vayapin/pins/{cwj_id}' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/vayapin/pins/{cwj_id}",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/vayapin/pins/{cwj_id}", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/vayapin/pins/{cwj_id}", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Get Vayapin Countries
Get country distribution for chart (honors the full filter bar).
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
search | query | any | false | |
country | query | any | false | |
status | query | any | false | |
has_seo | query | any | false | |
campaign_id | query | any | false | |
date_from | query | any | false | |
date_to | query | any | false |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/vayapin/countries' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/vayapin/countries",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/vayapin/countries", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/vayapin/countries", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Get Vayapin Campaigns
List campaigns (flows) that produced VayaPin PINs, for the filter dropdown.
Intentionally NOT filtered — it populates the campaign dropdown itself, so it must always show the full set of options regardless of the active filters.
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/vayapin/campaigns' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/vayapin/campaigns",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/vayapin/campaigns", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/vayapin/campaigns", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
Get Vayapin Timeline
Get daily export counts for timeline chart (honors the full filter bar).
When an explicit date range is set, it bounds the x-axis; otherwise the days lookback window applies.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
days | query | integer | false | |
search | query | any | false | |
country | query | any | false | |
status | query | any | false | |
has_seo | query | any | false | |
campaign_id | query | any | false | |
date_from | query | any | false | |
date_to | query | any | false |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/vayapin/timeline' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/vayapin/timeline",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/vayapin/timeline", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/vayapin/timeline", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |
Export Vayapin Csv
Export VayaPin rows as CSV (honors the active filter bar).
Mirrors /pins: shows ALL rows in scope (including failed / never-reached), with the mig-379 reason columns so a client can diagnose drops in a spreadsheet.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
search | query | any | false | |
country | query | any | false | |
status | query | any | false | |
has_seo | query | any | false | |
reason | query | any | false | Filter to rows whose fail_reason OR seo_reason matches |
campaign_id | query | any | false | |
date_from | query | any | false | |
date_to | query | any | false |
Try it
Examples
cURL
curl -X GET 'https://spideriq.ai/api/v1/dashboard/vayapin/export-csv' \
-H 'Authorization: Bearer <token>'Python
import httpx
resp = httpx.get(
"https://spideriq.ai/api/v1/dashboard/vayapin/export-csv",
headers={"Authorization": "Bearer <token>"},
)
resp.raise_for_status()
print(resp.json())JavaScript
const resp = await fetch("https://spideriq.ai/api/v1/dashboard/vayapin/export-csv", {
method: "GET",
headers: { "Authorization": "Bearer <token>" }
});
const data = await resp.json();
console.log(data);Go
package main
import (
"net/http"
)
func main() {
req, _ := http.NewRequest("GET", "https://spideriq.ai/api/v1/dashboard/vayapin/export-csv", nil)
req.Header.Set("Authorization", "Bearer <token>")
resp, _ := http.DefaultClient.Do(req)
defer resp.Body.Close()
}Responses
| Status | Description |
|---|---|
200 | Successful Response |
422 | Validation Error |