Skip to content
Pairfully
  • Product
  • Sample report
  • Pricing
  • Docs
Log inStart free

Docs

  • Install
  • MCP server
  • API reference

On this page

  • Authentication
  • Rate limits
  • Conventions
  • Endpoints
  • Errors
  • OpenAPI

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:

Header
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": "..." }. Pass nextCursor as cursor to get the next page; it is null on 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: true means 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.

Request
curl https://api.pairfully.com/v1/sites \
  -H "Authorization: Bearer $PAIRFULLY_API_KEY"
Response
{
  "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
Request
curl https://api.pairfully.com/v1/sites/site_8f2k1c/overview?range=7d \
  -H "Authorization: Bearer $PAIRFULLY_API_KEY"
Response
{
  "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
Request
curl https://api.pairfully.com/v1/sites/site_8f2k1c/reports/latest \
  -H "Authorization: Bearer $PAIRFULLY_API_KEY"
Response
{
  "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
Request
curl https://api.pairfully.com/v1/sites/site_8f2k1c/sessions?minIntent=3&converted=false&limit=20 \
  -H "Authorization: Bearer $PAIRFULLY_API_KEY"
Response
{
  "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.

Request
curl https://api.pairfully.com/v1/sites/site_8f2k1c/sessions/ses_7hq2 \
  -H "Authorization: Bearer $PAIRFULLY_API_KEY"
Response
{
  "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
Request
curl https://api.pairfully.com/v1/sites/site_8f2k1c/hot-visitors?since=2026-09-25T08:00:00Z \
  -H "Authorization: Bearer $PAIRFULLY_API_KEY"
Response
{
  "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
Request
curl https://api.pairfully.com/v1/sites/site_8f2k1c/leads?limit=20 \
  -H "Authorization: Bearer $PAIRFULLY_API_KEY"
Response
{
  "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
Request
curl https://api.pairfully.com/v1/sites/site_8f2k1c/compare?range=7d \
  -H "Authorization: Bearer $PAIRFULLY_API_KEY"
Response
{
  "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.

Request
curl https://api.pairfully.com/v1/sites/site_8f2k1c/alert-rules \
  -H "Authorization: Bearer $PAIRFULLY_API_KEY"
Response
{
  "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
Request
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}'
Response
{
  "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:

Response
{
  "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.

Pairfully

Why serious visitors left without buying, in your inbox every Monday.

Product

  • What you get
  • Sample report
  • How it decides
  • Pricing
  • Install guides
  • MCP server
  • API

Company

  • Why I built this
  • hello@pairfully.com
  • Log in

Legal

  • Privacy policy
  • Data sheet
  • Terms
  • Refund policy

© 2026 Pairfully