Docs
API reference
A small, versioned REST API over the same data as your dashboard: sites, weekly reports, exit reasons, sessions, hot visitors, leads and alert rules. JSON in, JSON out. Included on the Scale and Agency plans.
Authentication
Create a key in Settings → API. Owners and admins can create keys on the Scale and Agency plans. A key starts with pf_sk_, is shown once, and reads every site in its organisation. Send it as a Bearer token on every request:
Authorization: Bearer pf_sk_…Keys carry scopes. read is always included; alerts:write also lets the key create alert rules. Revoking a key in Settings stops it at once. Keep keys on the server: never put one in a browser or app bundle.
Want to use it from Claude or Cursor instead of code? See the MCP server.
Rate limits
- 60 requests a minute per key.
- 10,000 requests a day per key.
Over either limit, the API answers 429 with a Retry-After header in seconds. Wait that long before retrying. The limits count requests made through the MCP server too.
Conventions
- Base URL:
https://api.pairfully.com. Every path starts with/v1. - Lists come back as
{ "data": [...], "nextCursor": "..." }. PassnextCursorascursorto get the next page; it isnullon the last one. Single objects come back bare. - Timestamps are ISO 8601 in UTC. Shares and rates are ratios between 0 and 1.
- Intent levels run from 0 to 4: 0 No purchase intent, 1 Light interest, 2 Evaluating seriously, 3 Tried to buy or enquire, 4 Bought or one step away.
sampled: truemeans the site was over its quota and the figures are scaled up from a representative sample.
Endpoints
Examples are trimmed; … marks fields left out for length.
GET /v1/sites
Every site in the organisation the key belongs to.
curl https://api.pairfully.com/v1/sites \
-H "Authorization: Bearer $PAIRFULLY_API_KEY"{
"data": [
{
"id": "site_8f2k1c",
"name": "Northwind Coffee",
"domain": "northwind.coffee",
"type": "ECOMMERCE",
"timezone": "Europe/London",
"averageOrderValue": 120,
"installed": true,
"lastEventAt": "2026-09-25T09:41:12.000Z",
"createdAt": "2026-08-02T10:00:00.000Z"
}
]
}GET /v1/sites/{siteId}/overview
Totals, exit reasons, friction pages and the intent funnel for a range, against the period before.
- range7d (default), 30d or custom
- from, toYYYY-MM-DD, with range=custom
curl https://api.pairfully.com/v1/sites/site_8f2k1c/overview?range=7d \
-H "Authorization: Bearer $PAIRFULLY_API_KEY"{
"siteId": "site_8f2k1c",
"range": "7d",
"window": {
"from": "2026-09-18",
"to": "2026-09-25"
},
"previousWindow": {
"from": "2026-09-11",
"to": "2026-09-18"
},
"totals": {
"sessions": 4210,
"visitors": 3380,
"conversions": 96,
"conversionRate": 0.0228,
"seriousNonConverted": 214
},
"deltas": {
"sessions": 0.06,
"visitors": 0.04,
"conversions": -0.12,
"conversionRate": -0.17
},
"exitReasons": [
{
"reason": "shipping_cost",
"label": "Shipping cost",
"sessions": 58,
"share": 0.27,
"pages": [
"/checkout"
],
"estimatedImpact": {
"sessionsPerWeek": 12,
"revenue": 1440,
"currency": "USD"
}
}
],
"frictionPages": [
{
"path": "/checkout",
"page": "checkout",
"sessions": 71,
"share": 0.33,
"topReason": "shipping_cost",
"topReasonLabel": "Shipping cost"
}
],
"intentFunnel": [
{
"level": 3,
"label": "Tried to buy or enquire",
"sessions": 88
}
],
"unclear": {
"sessions": 11,
"share": 0.05
},
"unratedSessions": 402,
"sampled": false
}GET /v1/sites/{siteId}/reports
Weekly reports, newest first. /reports/latest returns the most recent one and /reports/{reportId} a single report, both as bare objects.
- limitHow many to return
curl https://api.pairfully.com/v1/sites/site_8f2k1c/reports/latest \
-H "Authorization: Bearer $PAIRFULLY_API_KEY"{
"id": "rep_31x9",
"siteId": "site_8f2k1c",
"weekStart": "2026-09-15",
"weekEnd": "2026-09-21",
"weekLabel": "Sep 15 – 21",
"sentAt": "2026-09-22T07:00:00.000Z",
"lede": "Shipping cost stopped 58 serious visitors at checkout, up from 41.",
"reasons": [
{
"reason": "shipping_cost",
"label": "Shipping cost",
"sessions": 58,
"share": 0.27,
"pages": [
"/checkout"
],
"estimatedImpact": {
"sessionsPerWeek": 12,
"revenue": 1440,
"currency": "USD"
}
}
],
"fixes": [
{
"rank": 1,
"reason": "shipping_cost",
"label": "Shipping cost",
"title": "Show shipping before checkout",
"action": "Put the delivery price on the product page and in the cart.",
"share": 0.27,
"pages": [
"/checkout"
],
"estimatedImpact": {
"sessionsPerWeek": 12,
"revenue": 1440,
"currency": "USD"
}
}
],
"stats": [
{
"key": "conversionRate",
"label": "Conversion rate",
"value": 0.0228,
"delta": -0.17
}
],
"frictionPages": [
"…"
],
"sources": [
{
"referrer": "google.com",
"sessions": 1840,
"conversions": 41,
"conversionRate": 0.0223
}
],
"unrated": 402,
"sampled": false
}GET /v1/sites/{siteId}/sessions
Visits, newest first, with the verdict on each. Paginate with nextCursor.
- from, toISO dates
- exitReasone.g. shipping_cost
- minIntent0–4
- convertedtrue or false
- cursor, limitPagination
curl https://api.pairfully.com/v1/sites/site_8f2k1c/sessions?minIntent=3&converted=false&limit=20 \
-H "Authorization: Bearer $PAIRFULLY_API_KEY"{
"data": [
{
"id": "ses_7hq2",
"startedAt": "2026-09-24T14:02:11.000Z",
"durationSeconds": 412,
"pages": 6,
"referrer": "google.com",
"device": "mobile",
"country": "GB",
"converted": false,
"verdict": {
"exitReason": "shipping_cost",
"exitReasonLabel": "Shipping cost",
"intentLevel": 3,
"intentLabel": "Tried to buy or enquire",
"visitorType": "new",
"frictionPage": "/checkout",
"clear": true
}
}
],
"nextCursor": "eyJpZCI6InNlc183aHEyIn0"
}GET /v1/sites/{siteId}/sessions/{sessionId}
One visit: everything in the list item, plus the path page by page and a plain-English account.
curl https://api.pairfully.com/v1/sites/site_8f2k1c/sessions/ses_7hq2 \
-H "Authorization: Bearer $PAIRFULLY_API_KEY"{
"id": "ses_7hq2",
"…": "…",
"path": [
{
"page": "/products/house-blend",
"seconds": 94,
"scroll": 0.8,
"clicks": 3,
"formErrors": 0,
"rageClicks": 0,
"errors": 0,
"exit": false
},
{
"page": "/checkout",
"seconds": 128,
"scroll": 0.6,
"clicks": 5,
"formErrors": 1,
"rageClicks": 0,
"errors": 0,
"exit": true
}
],
"story": "Came from Google, read the house blend, added it to the cart, left at checkout after seeing shipping.",
"reasons": {
"summary": "Left when the shipping cost appeared.",
"confused": false,
"hitDeadEnd": false
}
}GET /v1/sites/{siteId}/hot-visitors
Recent high-intent visitors. Defaults to the last 24 hours.
- sinceISO timestamp
curl https://api.pairfully.com/v1/sites/site_8f2k1c/hot-visitors?since=2026-09-25T08:00:00Z \
-H "Authorization: Bearer $PAIRFULLY_API_KEY"{
"data": [
{
"id": "hot_2m4",
"at": "2026-09-25T09:12:40.000Z",
"headline": "Comparing subscription plans on pricing for 6 minutes",
"page": "/pricing",
"intentLevel": 3,
"intentLabel": "Tried to buy or enquire",
"wantsHuman": true,
"device": "desktop",
"country": "US",
"sessionId": "ses_9a1k"
}
]
}GET /v1/sites/{siteId}/leads
Form submissions with fit, intent, route and a spam flag. Paginate with nextCursor.
- cursor, limitPagination
curl https://api.pairfully.com/v1/sites/site_8f2k1c/leads?limit=20 \
-H "Authorization: Bearer $PAIRFULLY_API_KEY"{
"data": [
{
"id": "lead_5r8",
"createdAt": "2026-09-24T16:30:00.000Z",
"fields": {
"company": "Harbour Cafés",
"message": "Wholesale pricing for 4 sites?"
},
"fit": {
"level": 3,
"label": "Good fit"
},
"intent": {
"level": 3,
"label": "Tried to buy or enquire"
},
"route": "sales",
"likelySpam": false,
"sessionId": "ses_4c0p"
}
],
"nextCursor": null
}GET /v1/sites/{siteId}/compare
This period against the one before, with the reasons and pages that moved most.
- range7d (default) or 30d
curl https://api.pairfully.com/v1/sites/site_8f2k1c/compare?range=7d \
-H "Authorization: Bearer $PAIRFULLY_API_KEY"{
"siteId": "site_8f2k1c",
"range": "7d",
"current": {
"window": {
"from": "2026-09-18",
"to": "2026-09-25"
},
"totals": {
"sessions": 4210,
"conversions": 96
}
},
"previous": {
"window": {
"from": "2026-09-11",
"to": "2026-09-18"
},
"totals": {
"sessions": 3970,
"conversions": 109
}
},
"deltas": {
"sessions": 0.06,
"conversions": -0.12
},
"exitReasons": [
{
"reason": "shipping_cost",
"label": "Shipping cost",
"current": {
"sessions": 58,
"share": 0.27
},
"previous": {
"sessions": 41,
"share": 0.2
},
"shareChange": 0.07,
"sessionsChange": 17
}
],
"frictionPages": [
"…"
],
"biggestMovers": {
"exitReasons": [
"…"
],
"frictionPages": [
"…"
]
}
}GET /v1/sites/{siteId}/alert-rules
Hot-visitor alert rules for the site.
curl https://api.pairfully.com/v1/sites/site_8f2k1c/alert-rules \
-H "Authorization: Bearer $PAIRFULLY_API_KEY"{
"data": [
{
"id": "rule_1",
"channel": "EMAIL",
"target": "sales@northwind.coffee",
"minIntent": 3,
"enabled": true,
"delivering": true,
"createdAt": "2026-09-01T12:00:00.000Z"
}
]
}POST /v1/sites/{siteId}/alert-rules
Email someone when a visitor reaches an intent level. Needs a key with the alerts:write scope. Returns 201 for a new rule, or 200 when a rule for that email already existed and was updated.
- emailRequired. Who to alert
- minIntent0–4, default 3
curl -X POST https://api.pairfully.com/v1/sites/site_8f2k1c/alert-rules \
-H "Authorization: Bearer $PAIRFULLY_API_KEY" \
-H "Content-Type: application/json" \
-d '{"email":"sales@northwind.coffee","minIntent":3}'{
"id": "rule_1",
"channel": "EMAIL",
"target": "sales@northwind.coffee",
"minIntent": 3,
"enabled": true,
"delivering": true,
"createdAt": "2026-09-25T10:00:00.000Z"
}Errors
Errors share one shape, with a stable code to branch on and a message for people:
{
"error": {
"code": "rate_limited",
"message": "Too many requests. Retry in 12 seconds."
}
}- 401 unauthorizedNo key, a malformed key, or a revoked one.
- 403 insufficient_scopeThe key lacks the scope this call needs, such as alerts:write.
- 403 plan_requiredThe organisation is not on Scale or Agency.
- 403 forbiddenThe key can’t reach this resource, such as a site in another organisation.
- 404 not_foundNo such site, report, session or route.
- 400 invalid_requestA parameter or body field is missing or out of range.
- 429 rate_limitedToo many requests. Wait for the Retry-After seconds.
- 500 internal_errorSomething failed on our side. Retry with backoff.
OpenAPI
The full schema, for generating a client or loading into Postman, is public and needs no key: https://api.pairfully.com/v1/openapi.json.
Response shapes under /v1 are stable. New fields may be added; nothing is renamed or removed without a new version.