Skip to content

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:

FieldPurpose
limitPage size.
cursorCreatedAtPagination cursor timestamp.
cursorIdPagination cursor id.
includeEvents=trueInclude 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/search

The 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, and transactionDate tuple.
FieldRequiredPurpose
environmentYesStripe environment: live or test.
amountWith the core tupleInteger amount in Stripe minor units.
currencyWith the core tupleThree-letter currency code.
transactionDateWith the core tupleISO 8601 transaction timestamp.
referenceWhen the core tuple is absentStripe reference evidence. Only exact ch_*, pi_*, or in_* IDs add an indexed reference match; other values require the core tuple.
windowDaysNoInclusive date window on either side of transactionDate; defaults to 3, range 0..7.
limitNoMaximum candidates; defaults to 1, range 1..100.
schemeNovisa or mastercard compatibility input; not used to filter core candidates.
cardBinNoCard BIN compatibility input; not used to filter core candidates.
cardLast4NoCard last-four fallback. It matches card last4 or wallet dynamic_last4.
authCodeNoStrong 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.

StatusMeaning
200Search completed, including a normal empty result.
400The request is invalid or the core tuple is incomplete.
401The integration secret key is missing or invalid.
503The lookup exceeded its deadline; retry with backoff.
500An 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.