Appearance
Integration API
Use the Integration API only from your backend. Authenticate with the project SDK secret key.
http
X-SDK-Secret-Key: <project-sdk-secret-key>Do not put the secret key in browser, mobile app, or published funnel code.
Get Funnel User
http
GET /integration/v1/funnel-users?funnelId=<funnel-id>&user_id=<user-id>You can look up a user by user_id, email, or funnelUserId.
sh
curl "https://sdk-api.funnelsgrove.com/integration/v1/funnel-users?funnelId=<funnel-id>&user_id=<user-id>" \
-H "X-SDK-Secret-Key: <project-sdk-secret-key>"Use this when your backend needs the full funnel user record, subscription state, payments, events, answers, and attribution.
List Funnel Users
http
GET /integration/v1/funnel-users/list?funnelId=<funnel-id>Optional query fields:
| Field | Purpose |
|---|---|
limit | Page size. |
cursorCreatedAt | Pagination cursor timestamp. |
cursorId | Pagination cursor id. |
includeEvents=true | Include event history in each user bundle. |
Search Stripe Transactions
Use transaction search from a trusted backend that needs Stripe payment evidence without maintaining a second copy of the project's transaction database. This is the integration boundary intended for a later ClaimBee Merchanto Prevent integration.
http
POST /integration/v1/transactions/searchThe legacy POST /sdk/private/transactions/search path remains available as a compatibility alias and uses the same handler and response contract.
The request must include environment plus either:
- an exact Stripe Charge (
ch_*), PaymentIntent (pi_*), or Invoice (in_*)reference; or - the complete
amount,currency, andtransactionDatetuple.
| Field | Required | Purpose |
|---|---|---|
environment | Yes | Stripe environment: live or test. |
amount | With the core tuple | Integer amount in Stripe minor units. |
currency | With the core tuple | Three-letter currency code. |
transactionDate | With the core tuple | ISO 8601 transaction timestamp. |
reference | When the core tuple is absent | Stripe reference evidence. Only exact ch_*, pi_*, or in_* IDs add an indexed reference match; other values require the core tuple. |
windowDays | No | Inclusive date window on either side of transactionDate; defaults to 3, range 0..7. |
limit | No | Maximum candidates; defaults to 1, range 1..100. |
scheme | No | visa or mastercard compatibility input; not used to filter core candidates. |
cardBin | No | Card BIN compatibility input; not used to filter core candidates. |
cardLast4 | No | Card last-four fallback. It matches card last4 or wallet dynamic_last4. |
authCode | No | Strong authorization-code evidence; an exact match wins over card fallback. |
sh
curl -sS "https://sdk-api.funnelsgrove.com/integration/v1/transactions/search" \
-H "X-SDK-Secret-Key: <project-sdk-secret-key>" \
-H "X-SDK-Request-Mode: shadow" \
-H "X-Request-ID: claimbee-shadow-<unique-id>" \
-H "Content-Type: application/json" \
--data '{
"environment": "live",
"scheme": "mastercard",
"cardLast4": "4444",
"amount": 3999,
"currency": "USD",
"transactionDate": "2026-08-10T12:00:00Z",
"windowDays": 3
}'A successful lookup returns normalized, project-scoped Stripe candidates:
json
{
"transactions": [
{
"id": "stripe-mirror-row-id",
"mode": "live",
"chargeId": "ch_123",
"paymentIntentId": "pi_123",
"invoiceId": "in_123",
"stripeCustomerId": "cus_123",
"customerEmail": "buyer@example.com",
"customerName": "Buyer Name",
"customerFirstName": "Buyer",
"customerLastName": "Name",
"customerPhone": "+15551234567",
"customerIpAddress": "8.8.8.8",
"amount": 3999,
"currency": "USD",
"transactionDate": "2026-08-10T12:00:00.000Z",
"cardBrand": "mastercard",
"cardBin": "555555",
"cardLast4": "4444",
"cardDynamicLast4": "1111",
"walletType": "apple_pay",
"authCode": "123456",
"networkTransactionId": "network-transaction-id",
"paymentDescriptor": "CLAIMBEE",
"stripePriceId": "price_123",
"stripeProductId": "prod_123",
"productName": "ClaimBee Annual Access",
"productDescription": "Annual ClaimBee access",
"productType": "subscription",
"productUrl": null,
"unitPriceAmount": 3999
}
]
}A normal miss returns 200 with { "transactions": [] }. Responses use Cache-Control: no-store. The route aborts stalled project and database reads after 800 milliseconds and returns a retryable 503 response.
Shadow rollout telemetry
During a parallel ClaimBee rollout, add X-SDK-Request-Mode: shadow to requests whose result does not drive the live response. Omit the header for primary traffic. Send a unique X-Request-ID for lookup-level correlation; FunnelsGrove echoes it in the response. You can also send X-Trace-ID to group several related requests in server telemetry.
Measure end-to-end latency in ClaimBee. FunnelsGrove additionally returns the server-side handler duration as Server-Timing: transaction-search;dur=<ms> on success and error responses. Server telemetry records the bounded outcome (found, empty, authentication/validation failure, timeout, or error), search strategy, candidate count, and counts of candidates that contain the important matching evidence: customer IP, authorization code, network transaction ID, card BIN/last four, customer contact fields, payment descriptor, and product ID.
Only presence counts are logged. Transaction IPs, card data, authorization codes, references, customer contact values, and request bodies are not copied into these telemetry fields.
| Status | Meaning |
|---|---|
200 | Search completed, including a normal empty result. |
400 | The request is invalid or the core tuple is incomplete. |
401 | The integration secret key is missing or invalid. |
503 | The lookup exceeded its deadline; retry with backoff. |
500 | An unexpected lookup error occurred. |
FunnelsGrove searches successful paid Charges by project, environment, amount, currency, and date, and can union an exact Stripe reference match. It does not discard core candidates based on the requested BIN, last four, scheme, authorization code, or network transaction ID. ClaimBee should keep ownership of that final card-network matching and ambiguity logic so network-tokenized cards can still match using stronger identifiers.
customerIpAddress is the public IP captured with the payment metadata. It is never replaced with the IP of the backend calling this endpoint. Raw Stripe payloads, unfiltered metadata, and internal project or integration IDs are not returned.