Payment performance over a date range
Returns the Payments > Performance page in one payload: three rates, the trend, decline reasons, breakdowns and checkouts that tried many cards, for the range and for the range of equal length just before it.
The three rates answer different questions.
checkout_success_rate is the share of checkouts with an
approved attempt, counting a checkout once however often it
retried. approval_rate is approved over answered attempts,
which retries pull down. card_approval_rate is distinct
checkout cards approved over distinct checkout cards tried,
which a stolen-card run moves most. Approval is the issuer’s
answer: an authorization counts when approved, before capture.
Decline reasons use Commerce::Payments::DeclineClassifier, the
classes renewal dunning acts on. Money is in the company’s
currency, or the selected country’s.
curl --request GET \
--url https://api.fluid.app/api/v202604/analytics/payments/overview \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.fluid.app/api/v202604/analytics/payments/overview"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.fluid.app/api/v202604/analytics/payments/overview', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.fluid.app/api/v202604/analytics/payments/overview",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.fluid.app/api/v202604/analytics/payments/overview"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.fluid.app/api/v202604/analytics/payments/overview")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fluid.app/api/v202604/analytics/payments/overview")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"from": "2026-10-06",
"to": "2026-10-07",
"previous_from": "2026-10-04",
"previous_to": "2026-10-05",
"time_zone": "America/Denver",
"currency": "USD",
"mode": "live",
"summary": {
"attempt_count": 120,
"approved_count": 104,
"declined_count": 16,
"pending_count": 0,
"approved_amount": "12480.0",
"checkout_attempt_count": 98,
"checkout_approved_count": 90,
"renewal_attempt_count": 22,
"renewal_approved_count": 14,
"checkout_count": 92,
"successful_checkout_count": 90,
"recovered_checkout_count": 5,
"recovered_amount": "640.0",
"unrecovered_checkout_count": 2,
"unrecovered_amount": "210.0",
"multi_card_checkout_count": 1,
"card_count": 101,
"approved_card_count": 96,
"unidentified_card_decline_count": 1,
"approval_rate": "86.7",
"checkout_success_rate": "97.8",
"checkout_approval_rate": "91.8",
"renewal_approval_rate": "63.6",
"card_approval_rate": "95.0"
},
"previous_summary": {
"attempt_count": 0,
"approved_count": 0,
"declined_count": 0,
"pending_count": 0,
"approved_amount": "0.0",
"checkout_attempt_count": 0,
"checkout_approved_count": 0,
"renewal_attempt_count": 0,
"renewal_approved_count": 0,
"checkout_count": 0,
"successful_checkout_count": 0,
"recovered_checkout_count": 0,
"recovered_amount": "0.0",
"unrecovered_checkout_count": 0,
"unrecovered_amount": "0.0",
"multi_card_checkout_count": 0,
"card_count": 0,
"approved_card_count": 0,
"unidentified_card_decline_count": 0,
"approval_rate": null,
"checkout_success_rate": null,
"checkout_approval_rate": null,
"renewal_approval_rate": null,
"card_approval_rate": null
},
"days": [
{
"date": "2026-10-06",
"attempt_count": 64,
"approved_count": 55,
"declined_count": 9,
"approved_amount": "6620.0",
"checkout_count": 49,
"successful_checkout_count": 48,
"approval_rate": "85.9",
"checkout_success_rate": "98.0"
},
{
"date": "2026-10-07",
"attempt_count": 56,
"approved_count": 49,
"declined_count": 7,
"approved_amount": "5860.0",
"checkout_count": 43,
"successful_checkout_count": 42,
"approval_rate": "87.5",
"checkout_success_rate": "97.7"
}
],
"decline_reasons": [
{
"category": "balance",
"declined_count": 9,
"checkout_count": 4,
"renewal_count": 5,
"share": "56.3",
"retriable": true,
"customer_caused": true,
"messages": [
{
"text": "Insufficient funds",
"count": 8
},
{
"text": "Exceeds withdrawal limit",
"count": 1
}
]
},
{
"category": "integration",
"declined_count": 2,
"checkout_count": 2,
"renewal_count": 0,
"share": "12.5",
"retriable": true,
"customer_caused": false,
"messages": []
}
],
"breakdowns": {
"flow": [
{
"key": "checkout",
"label": "Checkout",
"detail": null,
"attempt_count": 98,
"approved_count": 90,
"declined_count": 8,
"approved_amount": "11020.0",
"approval_rate": "91.8",
"top_decline_category": "soft_issuer"
}
],
"card_brand": [
{
"key": "visa",
"label": "Visa",
"detail": null,
"attempt_count": 80,
"approved_count": 70,
"declined_count": 10,
"approved_amount": "8400.0",
"approval_rate": "87.5",
"top_decline_category": "balance"
}
],
"payment_account": [
{
"key": "524",
"label": "Stripe US",
"detail": "Stripe",
"attempt_count": 120,
"approved_count": 104,
"declined_count": 16,
"approved_amount": "12480.0",
"approval_rate": "86.7",
"top_decline_category": "balance"
}
],
"payment_method": [
{
"key": "CreditCard",
"label": "Card",
"detail": null,
"attempt_count": 120,
"approved_count": 104,
"declined_count": 16,
"approved_amount": "12480.0",
"approval_rate": "86.7",
"top_decline_category": "balance"
}
],
"country": [
{
"key": "US",
"label": "United States",
"detail": null,
"attempt_count": 120,
"approved_count": 104,
"declined_count": 16,
"approved_amount": "12480.0",
"approval_rate": "86.7",
"top_decline_category": "balance"
}
]
},
"multi_card_checkouts": [
{
"email": "shopper@example.com",
"card_count": 3,
"attempt_count": 4,
"declined_count": 3,
"approved": true,
"last_attempt_at": "2026-10-07T02:18:23Z"
}
],
"payment_accounts": [
{
"id": 524,
"label": "Stripe US",
"detail": "Stripe"
}
]
}{
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"timestamp": "2023-11-07T05:31:56Z",
"request_id": "<string>",
"request_uuid": "<string>"
}
}{
"message": "<string>"
}{
"message": "<string>",
"error": "<string>"
}{
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"timestamp": "2023-11-07T05:31:56Z",
"request_id": "<string>",
"request_uuid": "<string>"
}
}Authorizations
Bearer token authentication. Requires a company-admin token
whose role holds reports.view.
Query Parameters
First day of the range, inclusive, as YYYY-MM-DD in the tz
zone. Defaults to 29 days before to, so the default range is
thirty days. A value that is not this exact shape returns 400.
"2026-09-08"
Last day of the range, inclusive, as YYYY-MM-DD in the tz
zone. Defaults to today, or to 29 days after from when only
from is sent. A range longer than 92 days, or one that ends
before it starts, returns 400.
"2026-10-07"
IANA timezone name (e.g. America/Denver) or Rails-style
alias (Eastern Time (US & Canada)) used to anchor
"today" boundaries and hour-of-day bucketing. The
frontend sends
Intl.DateTimeFormat().resolvedOptions().timeZone.
Unknown or malformed values silently fall back to UTC —
callers omit the param when the endpoint doesn't need
wall-clock alignment (see CURRENT-3077).
"America/Denver"
ISO alpha-2 code of one of the requesting company's configured
countries (see GET /countries). When present, every service
on this endpoint filters its data to that country and reports
money in the country's own currency. Omit (or send "all")
for the aggregate-across-countries view, which is the default
and matches pre-Phase-004 behavior. Unknown ISO codes or ones
the company is not configured for return 400.
"US"
Which payments to report on. live (the default) is real money
through a live account at a real gateway. test is every test
or sandbox account and the Bogus gateway, so a merchant who is
still integrating can watch their own test traffic.
live, test "live"
Narrow every figure to one flow. checkout is an attempt with a
cart; renewal is a subscription renewal with no cart. all,
the default, keeps both.
all, checkout, renewal "all"
Narrow every figure to one of the company's payment accounts, by
the id listed in payment_accounts. An id that is not one of
the company's accounts returns 400.
^[0-9]+$"524"
Response
Payment performance payload
First day of the range of equal length just before.
IANA name of the zone the dates are cut in.
ISO 4217 three-letter code (uppercase).
3"USD"
live, test Counts for one range. Pending attempts are counted in
attempt_count but are in no rate's denominator.
Show child attributes
Show child attributes
Counts for one range. Pending attempts are counted in
attempt_count but are in no rate's denominator.
Show child attributes
Show child attributes
One entry per date of the range, zero-filled.
Show child attributes
Show child attributes
Most declines first.
Show child attributes
Show child attributes
Each dimension's rows, most attempts first. After eight rows
the rest fold into one other row. Card brand counts card
payments only.
Show child attributes
Show child attributes
Checkouts that tried three or more different cards, most cards first. Many cards on one cart is how a stolen-card run looks from the merchant's side.
10Show child attributes
Show child attributes
The company's kept accounts in this mode, for the filter.
Show child attributes
Show child attributes
Show child attributes
Show child attributes
curl --request GET \
--url https://api.fluid.app/api/v202604/analytics/payments/overview \
--header 'Authorization: Bearer <token>'import requests
url = "https://api.fluid.app/api/v202604/analytics/payments/overview"
headers = {"Authorization": "Bearer <token>"}
response = requests.get(url, headers=headers)
print(response.text)const options = {method: 'GET', headers: {Authorization: 'Bearer <token>'}};
fetch('https://api.fluid.app/api/v202604/analytics/payments/overview', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.fluid.app/api/v202604/analytics/payments/overview",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "GET",
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"net/http"
"io"
)
func main() {
url := "https://api.fluid.app/api/v202604/analytics/payments/overview"
req, _ := http.NewRequest("GET", url, nil)
req.Header.Add("Authorization", "Bearer <token>")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.get("https://api.fluid.app/api/v202604/analytics/payments/overview")
.header("Authorization", "Bearer <token>")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fluid.app/api/v202604/analytics/payments/overview")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Get.new(url)
request["Authorization"] = 'Bearer <token>'
response = http.request(request)
puts response.read_body{
"from": "2026-10-06",
"to": "2026-10-07",
"previous_from": "2026-10-04",
"previous_to": "2026-10-05",
"time_zone": "America/Denver",
"currency": "USD",
"mode": "live",
"summary": {
"attempt_count": 120,
"approved_count": 104,
"declined_count": 16,
"pending_count": 0,
"approved_amount": "12480.0",
"checkout_attempt_count": 98,
"checkout_approved_count": 90,
"renewal_attempt_count": 22,
"renewal_approved_count": 14,
"checkout_count": 92,
"successful_checkout_count": 90,
"recovered_checkout_count": 5,
"recovered_amount": "640.0",
"unrecovered_checkout_count": 2,
"unrecovered_amount": "210.0",
"multi_card_checkout_count": 1,
"card_count": 101,
"approved_card_count": 96,
"unidentified_card_decline_count": 1,
"approval_rate": "86.7",
"checkout_success_rate": "97.8",
"checkout_approval_rate": "91.8",
"renewal_approval_rate": "63.6",
"card_approval_rate": "95.0"
},
"previous_summary": {
"attempt_count": 0,
"approved_count": 0,
"declined_count": 0,
"pending_count": 0,
"approved_amount": "0.0",
"checkout_attempt_count": 0,
"checkout_approved_count": 0,
"renewal_attempt_count": 0,
"renewal_approved_count": 0,
"checkout_count": 0,
"successful_checkout_count": 0,
"recovered_checkout_count": 0,
"recovered_amount": "0.0",
"unrecovered_checkout_count": 0,
"unrecovered_amount": "0.0",
"multi_card_checkout_count": 0,
"card_count": 0,
"approved_card_count": 0,
"unidentified_card_decline_count": 0,
"approval_rate": null,
"checkout_success_rate": null,
"checkout_approval_rate": null,
"renewal_approval_rate": null,
"card_approval_rate": null
},
"days": [
{
"date": "2026-10-06",
"attempt_count": 64,
"approved_count": 55,
"declined_count": 9,
"approved_amount": "6620.0",
"checkout_count": 49,
"successful_checkout_count": 48,
"approval_rate": "85.9",
"checkout_success_rate": "98.0"
},
{
"date": "2026-10-07",
"attempt_count": 56,
"approved_count": 49,
"declined_count": 7,
"approved_amount": "5860.0",
"checkout_count": 43,
"successful_checkout_count": 42,
"approval_rate": "87.5",
"checkout_success_rate": "97.7"
}
],
"decline_reasons": [
{
"category": "balance",
"declined_count": 9,
"checkout_count": 4,
"renewal_count": 5,
"share": "56.3",
"retriable": true,
"customer_caused": true,
"messages": [
{
"text": "Insufficient funds",
"count": 8
},
{
"text": "Exceeds withdrawal limit",
"count": 1
}
]
},
{
"category": "integration",
"declined_count": 2,
"checkout_count": 2,
"renewal_count": 0,
"share": "12.5",
"retriable": true,
"customer_caused": false,
"messages": []
}
],
"breakdowns": {
"flow": [
{
"key": "checkout",
"label": "Checkout",
"detail": null,
"attempt_count": 98,
"approved_count": 90,
"declined_count": 8,
"approved_amount": "11020.0",
"approval_rate": "91.8",
"top_decline_category": "soft_issuer"
}
],
"card_brand": [
{
"key": "visa",
"label": "Visa",
"detail": null,
"attempt_count": 80,
"approved_count": 70,
"declined_count": 10,
"approved_amount": "8400.0",
"approval_rate": "87.5",
"top_decline_category": "balance"
}
],
"payment_account": [
{
"key": "524",
"label": "Stripe US",
"detail": "Stripe",
"attempt_count": 120,
"approved_count": 104,
"declined_count": 16,
"approved_amount": "12480.0",
"approval_rate": "86.7",
"top_decline_category": "balance"
}
],
"payment_method": [
{
"key": "CreditCard",
"label": "Card",
"detail": null,
"attempt_count": 120,
"approved_count": 104,
"declined_count": 16,
"approved_amount": "12480.0",
"approval_rate": "86.7",
"top_decline_category": "balance"
}
],
"country": [
{
"key": "US",
"label": "United States",
"detail": null,
"attempt_count": 120,
"approved_count": 104,
"declined_count": 16,
"approved_amount": "12480.0",
"approval_rate": "86.7",
"top_decline_category": "balance"
}
]
},
"multi_card_checkouts": [
{
"email": "shopper@example.com",
"card_count": 3,
"attempt_count": 4,
"declined_count": 3,
"approved": true,
"last_attempt_at": "2026-10-07T02:18:23Z"
}
],
"payment_accounts": [
{
"id": 524,
"label": "Stripe US",
"detail": "Stripe"
}
]
}{
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"timestamp": "2023-11-07T05:31:56Z",
"request_id": "<string>",
"request_uuid": "<string>"
}
}{
"message": "<string>"
}{
"message": "<string>",
"error": "<string>"
}{
"error": {
"message": "<string>",
"details": {}
},
"meta": {
"timestamp": "2023-11-07T05:31:56Z",
"request_id": "<string>",
"request_uuid": "<string>"
}
}