ShonyLabs
DocsPricingChangelog
Log inGet started

Getting started

IntroductionQuickstart

Tracking

Tracking snippetCustom goalsIdentify usersExclusions

Privacy

GDPR & cookieless tracking

Revenue

Transactions APIPayment connectors

Server & bots

Bots & server-side tracking

Collaboration

Team & access

Live map

Public live map

Integrations

Google Search Console

No-code platforms

WordPressGoogle Tag ManagerWebflowWixSquarespaceFramerGhostOther platforms

Reference

API reference

Transactions API

Report a purchase, refund, or deletion from your own backend, independent of any specific payment processor.

Log in to jump straight to your site's Settings → API to generate a key.

Recording a purchase

Call this from your backend right after a successful checkout — e.g. from a payment webhook. It works the same way regardless of which payment processor you use, since it's a plain HTTP endpoint rather than a processor-specific integration.

cURL
curl -X POST https://api.shonylabs.com/v1/transactions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "transaction_id": "order_9F2K",
    "shonylabs_visitor_id": "<value of the shonylabs_visitor_id cookie>",
    "amount": 49.00,
    "currency": "USD",
    "customer_email": "[email protected]",
    "renewal": false,
    "metadata": {
      "plan": "pro",
      "sku": "PRO-ANNUAL",
      "coupon": "LAUNCH20"
    }
  }'
FieldRequiredNotes
transaction_idYesYour own order ID. Acts as an idempotency key — retried webhook deliveries record the sale once.
shonylabs_visitor_idYesRead from the first-party shonylabs_visitor_id cookie the tracking snippet sets — this links the sale back to the visitor who made it.
amountYesA non-negative number, e.g. 49.00.
currencyNoUp to 10 characters, e.g. USD.
customer_email / emailNoEither key name is accepted. Helps match free trials to later payments.
customer_name / nameNoEither key name is accepted.
customer_idNoStable customer ID from your own billing system.
renewalNoBoolean. Whether this is a recurring renewal rather than a first purchase.
is_free_trialNoBoolean. Whether this represents a free trial rather than a paid charge.
metadataNoA flat JSON object of your own key/value pairs — plan name, product SKU, coupon code, anything you want attached to this specific sale. Up to 20 keys; each key up to 64 characters (letters, numbers, underscore, or hyphen) and each value up to 500 characters. Values are coerced to strings and unrecognized keys/values beyond those limits are dropped rather than rejecting the whole request.
timestampNoISO 8601 event time. Defaults to the time the request is received.

Metadata shows up in the dashboard's Transactions pageas a small tag icon next to the transaction ID — hover it to see every key/value pair. It can also be edited directly from that page's Edit action, independent of this API.

Refunds

Call the same endpoint again with refunded: true and the original transaction_id — the revenue is netted back out rather than deleting the original sale.

cURL
curl -X POST https://api.shonylabs.com/v1/transactions \
  -H "Authorization: Bearer YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "transaction_id": "order_9F2K",
    "refunded": true
  }'

Deleting a payment

Use DELETE /v1/transactions to fully remove a wrongly-recorded payment — unlike a refund, this deletes the transaction and its revenue attribution outright rather than netting it out. Provide exactly one filter: a single transaction_id (or tx_id), a shonylabs_visitor_id to remove every payment for one visitor, or a start/end ISO 8601 range to bulk-delete by when the payment was recorded.

cURL — by transaction
curl -X DELETE "https://api.shonylabs.com/v1/transactions?transaction_id=order_9F2K" \
  -H "Authorization: Bearer YOUR_API_KEY"
cURL — by date range
curl -X DELETE "https://api.shonylabs.com/v1/transactions?start=2026-05-01T00:00:00Z&end=2026-05-19T23:59:59Z" \
  -H "Authorization: Bearer YOUR_API_KEY"

A successful response returns { "status": "success", "data": [...] }, with one entry per deleted payment. Deleting a transaction_id that doesn't exist returns 404; the visitor and date-range filters return an empty data array instead when nothing matches.

No backend? Report revenue from the browser instead

This API is the recommended way to record revenue because it's authenticated with your site's API key — a visitor can never fake a payment through it. If your checkout has no backend of its own to call it from (a static site or a no-code storefront, for example), turn on Allow revenue from the browser tracker under Settings → API and call this from the page after a successful checkout instead — for example on a Stripe Checkout success_url page, or wherever your storefront redirects after payment:

JavaScript
window.shonylabs('purchase', {
  revenue: 19.99,
  currency: 'USD',
  transaction_id: 'order_9F2K'
});

transaction_idis optional but recommended — it isn't a reserved property, so it's stored as an ordinary custom field alongside the event, visible in the visitor's activity feed. This setting is off by default: enabling it means anyone who opens devtools on your site can also call window.shonylabs('purchase', { revenue: 999999 }) and report fake revenue, so only turn it on if you accept that trade-off.

Unlike POST /v1/transactions, this path has no server-side idempotency check on transaction_id— calling it twice for the same order records the revenue twice. If the same page can fire this more than once (a visitor refreshing a "thank you" page is the common case), guard it client-side:
JavaScript
const orderId = 'order_9F2K';
if (sessionStorage.getItem('shonylabs_reported_order') !== orderId) {
  window.shonylabs('purchase', { revenue: 19.99, currency: 'USD', transaction_id: orderId });
  sessionStorage.setItem('shonylabs_reported_order', orderId);
}
ShonyLabs Analytics

Privacy-friendly web analytics that shows which channels actually drive revenue.

© 2026 ShonyLabs. All rights reserved.

Product

  • Log in
  • Sign up
  • Pricing
  • Changelog
  • Documentation
  • API reference

Guides

  • Quickstart
  • Tracking snippet
  • Goals
  • Transactions
  • Identify visitors
  • Cookieless tracking

Legal

  • Terms of service
  • Privacy policy
  • Data processing agreement