CartSpy Merchant API

Read-only API for accessing your store's analytics data programmatically

Contents

Authentication

All requests require a merchant API key sent via the Authorization header:

Authorization: Bearer csk_your_api_key_here

Generate an API key from the Settings page in your CartSpy dashboard. Each store can have one active key at a time. Revoking a key invalidates it immediately.

Base URL

https://app.cartspy.app

All API endpoints are relative to this base URL. For example, the abandoned carts endpoint is:

https://app.cartspy.app/api/v1/abandoned-carts

Rate Limiting

API requests are limited to 120 requests per hour per API key. When the limit is exceeded, you'll receive a 429 Too Many Requests response.

Rate limit headers are included in every response:

HeaderDescription
X-RateLimit-LimitMaximum requests per window
X-RateLimit-RemainingRemaining requests in current window
Retry-AfterSeconds until the limit resets (only on 429)

Error Handling

All errors return a JSON body with success: false and an error message.

StatusMeaning
400Bad request (e.g., date range exceeds maximum)
401Missing or invalid API key
422Validation failed (missing or invalid parameters)
429Rate limit exceeded
500Internal server error
{
    "success": false,
    "error": "Validation failed",
    "details": {
        "start_date": ["The start date field is required."]
    }
}

GET/api/v1/abandoned-carts

Retrieve abandoned cart analytics for your store.

Parameters

ParameterTypeDescription
start_datestringrequiredStart date (YYYY-MM-DD)
end_datestringrequiredEnd date (YYYY-MM-DD). Max 90-day range.
pageintegeroptionalPage number (default: 1)
per_pageintegeroptionalResults per page, 1-50 (default: 50)
sort_bystringoptionalSort field: cart_value, item_count, abandonment_stage, abandoned_at (default)
sort_directionstringoptionalasc or desc (default)

Example

curl -s "https://app.cartspy.app/api/v1/abandoned-carts?start_date=2026-03-01&end_date=2026-03-14" \
  -H "Authorization: Bearer csk_your_key"

Response

{
    "success": true,
    "data": [
        {
            "id": "cart_abc123",
            "customer_email": "customer@example.com",
            "customer_phone": "+1234567890",
            "location": "New York, NY, US",
            "cart_value": 89.99,
            "currency": "USD",
            "item_count": 3,
            "abandonment_stage": "checkout",
            "abandoned_at": "2026-03-10T14:30:00+00:00",
            "utm_source": "facebook",
            "utm_medium": "cpc",
            "utm_campaign": "spring_sale",
            "utm_content": null,
            "utm_term": null,
            "first_utm_source": "google",
            "first_utm_medium": "organic",
            "first_utm_campaign": null,
            "first_utm_content": null,
            "first_utm_term": null,
            "referrer": "facebook.com",
            "first_referrer": "google.com",
            "products": [...],
            "device_info": {...}
        }
    ],
    "pagination": {
        "current_page": 1,
        "per_page": 50,
        "total": 142,
        "total_pages": 3,
        "has_next_page": true,
        "has_prev_page": false
    }
}

GET/api/v1/carts/active

Retrieve currently active (non-empty) carts on your store.

Parameters

ParameterTypeDescription
pageintegeroptionalPage number (default: 1)
per_pageintegeroptionalResults per page, 1-50 (default: 50)

Example

curl -s "https://app.cartspy.app/api/v1/carts/active?per_page=10" \
  -H "Authorization: Bearer csk_your_key"

Response

{
    "success": true,
    "data": [
        {
            "client_id": "vis_abc123",
            "customer_name": "John Doe",
            "current_cart": [...],
            "last_activity_at": "2026-03-14T09:15:00+00:00",
            "last_page_url": "/products/example",
            "last_page_title": "Example Product",
            "utm_source": "facebook",
            "utm_medium": "cpc",
            "utm_campaign": "spring_sale",
            "referrer": "facebook.com",
            "device_type": "mobile",
            "browser": "Chrome",
            "os": "iOS"
        }
    ],
    "pagination": {
        "current_page": 1,
        "per_page": 10,
        "total": 35,
        "total_pages": 4,
        "has_next_page": true,
        "has_prev_page": false
    }
}

GET/api/v1/events

Retrieve raw tracking events. Uses cursor-based pagination via after_id.

Parameters

ParameterTypeDescription
start_datestringrequiredStart date (YYYY-MM-DD)
end_datestringrequiredEnd date (YYYY-MM-DD). Max 30-day range.
event_typestringoptionalFilter by event type (e.g., product_viewed, checkout_completed)
after_idintegeroptionalReturn events with ID less than this (for pagination)
limitintegeroptionalResults per page, 1-100 (default: 100)

Example

curl -s "https://app.cartspy.app/api/v1/events?start_date=2026-03-10&end_date=2026-03-14&event_type=checkout_completed" \
  -H "Authorization: Bearer csk_your_key"

Response

{
    "success": true,
    "data": [
        {
            "id": 98765,
            "type": "standard",
            "name": "checkout_completed",
            "client_id": "vis_abc123",
            "customer_name": "John Doe",
            "context": {...},
            "data": {...},
            "utm_source": "facebook",
            "utm_medium": "cpc",
            "utm_campaign": "spring_sale",
            "utm_content": null,
            "utm_term": null,
            "referrer": "facebook.com",
            "ip_location": {...},
            "created_at": "2026-03-12T16:45:00+00:00"
        }
    ],
    "pagination": {
        "has_more": true,
        "next_after_id": 98700
    }
}
To paginate through all events, pass the next_after_id value from the response as after_id in your next request. Continue until has_more is false.

GET/api/v1/analytics/products

Retrieve product performance analytics with conversion rates. Ordered by date (ascending) then revenue (descending).

Parameters

ParameterTypeDescription
start_datestringrequiredStart date (YYYY-MM-DD)
end_datestringrequiredEnd date (YYYY-MM-DD). Max 90-day range.
pageintegeroptionalPage number (default: 1)
per_pageintegeroptionalResults per page, 1-50 (default: 50)

Example

curl -s "https://app.cartspy.app/api/v1/analytics/products?start_date=2026-03-01&end_date=2026-03-14" \
  -H "Authorization: Bearer csk_your_key"

Response

{
    "success": true,
    "data": [
        {
            "date": "2026-03-01",
            "product_id": "8012345678",
            "product_title": "Classic Leather Wallet",
            "product_url": "/products/classic-leather-wallet",
            "views": 245,
            "add_to_cart_count": 38,
            "atc_rate": 15.51,
            "checkout_count": 22,
            "checkout_rate": 57.89,
            "order_count": 18,
            "order_rate": 81.82,
            "items_sold": 21,
            "revenue": 1259.79
        }
    ],
    "pagination": {
        "current_page": 1,
        "per_page": 50,
        "total": 320,
        "total_pages": 7,
        "has_next_page": true,
        "has_prev_page": false
    }
}
Computed rates: atc_rate = (add_to_cart / views) × 100, checkout_rate = (checkouts / add_to_cart) × 100, order_rate = (orders / checkouts) × 100. All rates are percentages rounded to 2 decimal places.

GET/api/v1/analytics/traffic

Retrieve traffic source attribution data broken down by UTM parameters. Ordered by revenue (descending).

Parameters

ParameterTypeDescription
start_datestringrequiredStart date (YYYY-MM-DD)
end_datestringrequiredEnd date (YYYY-MM-DD). Max 90-day range.
pageintegeroptionalPage number (default: 1)
per_pageintegeroptionalResults per page, 1-50 (default: 50)

Example

curl -s "https://app.cartspy.app/api/v1/analytics/traffic?start_date=2026-03-01&end_date=2026-03-14" \
  -H "Authorization: Bearer csk_your_key"

Response

{
    "success": true,
    "data": [
        {
            "date": "2026-03-01",
            "utm_source": "facebook",
            "utm_medium": "cpc",
            "utm_campaign": "spring_sale_2026",
            "utm_content": "carousel_ad_v2",
            "utm_term": "leather wallets",
            "views": 1820,
            "unique_visitors": 1540,
            "add_to_cart_count": 156,
            "checkout_count": 89,
            "order_count": 72,
            "revenue": 5439.28
        }
    ],
    "pagination": {
        "current_page": 1,
        "per_page": 50,
        "total": 85,
        "total_pages": 2,
        "has_next_page": true,
        "has_prev_page": false
    }
}

Data Freshness

Product performance and traffic attribution data is aggregated daily. Records for the current day are updated throughout the day but may not reflect the very latest events until the next aggregation cycle.

Abandoned carts, active carts, and raw events are available in near real-time.