Docs

Build your App Probe

Stripe can tell BillingGuard what a customer pays for. The App Probe tells BillingGuard what your application actually grants. The reconciliation between those two views is an optional advanced signal on top of Stripe monitoring.

Read-only

Return state only. Do not expose mutation actions.

Minimal fields

Customer mapping, plan and active/inactive access are enough.

Authenticated

Require a strong shared Bearer secret on every request.

Expected response

Return JSON with a top-level customers array. Each item should map your internal user to a Stripe customer and describe the access currently granted by your application.

{
  "version": 1,
  "customers": [
    {
      "external_user_id": "user_123",
      "stripe_customer_id": "cus_123",
      "plan": "Pro",
      "access_status": "active"
    }
  ]
}

Next.js example

Adapt the database query to your own schema. Keep the endpoint HTTPS in production and make sure the secret is stored in a server-side environment variable.

export async function GET(request: Request) {
  const auth = request.headers.get("authorization");

  if (auth !== `Bearer ${process.env.BILLINGGUARD_PROBE_SECRET}`) {
    return new Response("Unauthorized", { status: 401 });
  }

  const customers = await db.user.findMany({
    select: {
      id: true,
      stripeCustomerId: true,
      plan: true,
      hasPaidAccess: true,
    },
  });

  return Response.json({
    version: 1,
    customers: customers.map((customer) => ({
      external_user_id: customer.id,
      stripe_customer_id: customer.stripeCustomerId,
      plan: customer.plan,
      access_status: customer.hasPaidAccess ? "active" : "inactive",
    })),
  });
}

Production checklist

Use HTTPS
Use a strong random secret of at least 24 characters
Return only the fields required for reconciliation
Keep the endpoint read-only
Rotate the secret from BillingGuard Settings when needed