Harvv API

Access your behavioral analytics data programmatically. Use with the Claude Code plugin or build your own integrations.

Authentication

All requests require an API key in the Authorization header:

Authorization: Bearer hv_live_your_api_key_here

Create API keys at harvv.com → Settings → API Keys.

Endpoints

GET /v1/sites

List all your sites.

curl -H "Authorization: Bearer hv_live_xxx" https://harvv.com/v1/sites

GET /v1/sites/:id/stats

Get site analytics (sessions, visitors, dead clicks, rage clicks).

ParamDescription
period7d (default), 30d, or today
curl -H "Authorization: Bearer hv_live_xxx" "https://harvv.com/v1/sites/SITE_ID/stats?period=30d"

GET /v1/sites/:id/issues

Get detected UX issues with descriptions, severity, and fix suggestions.

ParamDescription
statusFilter: open, quoted, approved, fixing, in_qa, resolved, dismissed
curl -H "Authorization: Bearer hv_live_xxx" "https://harvv.com/v1/sites/SITE_ID/issues?status=open"

GET /v1/sites/:id/issues/:issue_id

Get full details for a specific issue including fix suggestion.

curl -H "Authorization: Bearer hv_live_xxx" "https://harvv.com/v1/sites/SITE_ID/issues/123"

GET /v1/sites/:id/friction

Get top friction elements (dead clicks + rage clicks by element and page section).

ParamDescription
period7d (default) or 30d
curl -H "Authorization: Bearer hv_live_xxx" "https://harvv.com/v1/sites/SITE_ID/friction?period=30d"

POST /customer/api-keys

Create a new API key (requires JWT auth, not API key).

curl -X POST -H "Authorization: Bearer JWT_TOKEN" -H "Content-Type: application/json" \
  -d '{"name":"My Integration"}' https://harvv.com/customer/api-keys

Outcomes — stitch client friction to your business events

Harvv's pixel captures behavioral friction at the DOM layer (dead clicks, rage clicks, hover-abandon, etc.). For an honest "did this friction actually block the user?" answer, you can tell Harvv when your application reaches a meaningful state — server-side via webhook, or client-side via a one-line JS call. Both are optional. Both improve our case severity scoring.

Client-side: window.harvv.outcome()

From your app after a meaningful event (form submitted, purchase completed, KYC approved, lead captured, etc.):

// minimal
window.harvv?.outcome('kyc_submitted');

// with whitelisted properties
window.harvv?.outcome('purchase_completed', {
  value: 99.00,           // number — currency totals are useful
  currency: 'USD',        // string ≤100 chars
  step: 'individual',     // string
  is_returning: true      // boolean
});

PII guard: the call is silently dropped if any property name or value looks like an email, phone, SSN, credit card number, or password. Don't pass customer_email, phone_number, card_number, etc. — use opaque IDs instead.

Caps: up to 12 properties per call, each value capped at 100 chars / numeric type. Properties beyond the cap are silently dropped.

Outcomes show up in the dashboard tied to the same session that generated the friction, so cases get an honest "real users actually completed this flow" signal.

POST /v1/outcomes — server-side webhook

For the authoritative version of the same signal — call this from your backend when an outcome is confirmed (KYC approval, order paid, lead qualified). This is the strongest possible "did the user get through?" signal because it's coming from your system of record.

curl -X POST https://harvv.com/v1/outcomes \
  -H "Authorization: Bearer hv_live_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "site_id": "your-pixel-key",
    "session_id": "61b7df69",
    "outcome": "kyc_approved",
    "timestamp": 1763760000000,
    "properties": {
      "approval_tier": "instant",
      "score": 87
    }
  }'
FieldRequiredNotes
site_idYesYour pixel key (visible in dashboard → Settings → Install snippet)
session_idYesThe 8-char session ID from the pixel. Read on the client via window.harvv.sessionId (or call window.harvv.getSessionId()), pass through your form/order as a hidden field, then forward server-side. See the "Reading the session ID" section below.
outcomeYesSnake-case name, max 60 chars. e.g. kyc_approved, order_paid, lead_qualified
timestampNoUnix milliseconds. Defaults to now.
propertiesNoSame PII guard as the client API — emails/phones/cards rejected; whole event dropped if any field flagged.

Reading the session ID

To call /v1/outcomes from your backend, your server needs to know which pixel session it's confirming. Read the ID from the pixel on the client, then send it along with whatever request you're making to your backend (form submit, order create, API call):

// On the client — read directly:
const sessionId = window.harvv?.sessionId;
const visitorId = window.harvv?.visitorId;

// Or via accessor functions (useful if pixel may not have loaded yet):
const sessionId = window.harvv?.getSessionId?.();
const visitorId = window.harvv?.getVisitorId?.();

// Then either stuff into a hidden form field…
<input type="hidden" name="harvv_session_id" value="..." />

// …or include in your API payload:
fetch('/api/orders', {
  method: 'POST',
  body: JSON.stringify({ /* your data */, harvv_session_id: sessionId })
});

Both IDs are non-PII. Session ID is an 8-char random string scoped to a single browser session (~30min idle timeout). Visitor ID is also random, persisted in a first-party cookie for ~30 days as a device signal. Neither is linkable to a named person without your help. You can log them freely in your own systems.

Form submission detection (automatic)

Your pixel already captures form submissions and same-origin API success — no code change required. We listen for:

We store the URL path template (with numeric IDs and UUIDs collapsed to :id / :uuid) and the response status code. Never the request body, response body, headers, or query string. If a session hits friction and a same-session form-submit succeeds within 30 seconds, the case is automatically downgraded to "frustration but not blocking."

What you can do to make it more accurate

For paths that don't match the default heuristic (e.g. /complete, /finalize), call window.harvv?.outcome() on success. Customer-side outcome calls always win over the heuristic.

Privacy guarantees (everything above)

Claude Code Plugin

Install Harvv directly in Claude Code:

/plugin install github:harvv/claude-plugin

Then use:

CommandWhat it does
/harvv:installInstall pixel into your project
/harvv:issuesSee detected UX issues
/harvv:fix 123Apply AI fix for issue #123
/harvv:whyFull conversion diagnosis

Rate Limits

EndpointLimit
/v1/*60 requests/minute

© 2026 Harvv — harvv.com