Checkout Status

Poll for Stripe checkout completion. Response shape depends on whether the session was started in anonymous or authenticated mode.

GEThttps://api.boringmarketing.com/auth/checkout/{session_id}/status

Polls for completion of a checkout session started with POST /auth/checkout. No authentication required — the opaque session_id from the checkout response is the correlator.

This endpoint never returns an API key. In an earlier version of the API, the poll endpoint returned api_key directly via a claim-once pattern. That path was closed because it let any caller who obtained a session_id claim the key after payment. Anonymous signups now retrieve their key via the dashboard with a magic-link login.

Path parameters

session_idstringrequired

The session_id returned from POST /auth/checkout. An opaque bmc_ correlator — the format does not leak account state.

Response shapes

The response depends on the session's server-recorded auth_mode and session_kind. There are four terminal states.

1. Pending

Payment has not completed. Poll again in 3-5 seconds.

{ "status": "pending" }

2. Completed — anonymous checkout

{
  "status": "completed",
  "dashboard_url": "https://dashboard.boringmarketing.com"
}

Stripe payment landed and the user's account was created or reactivated. There is no api_key field. To retrieve the key:

  1. Open dashboard_url in a browser.
  2. Enter the email used during checkout → receive a magic-link.
  3. Click the link → land in the dashboard.
  4. Copy the key from Settings → API Access.

3. Completed — authenticated checkout

{
  "status": "completed",
  "tier": "pro",
  "calls_per_day": 5000,
  "brand_limit": 3
}

Stripe payment landed and the caller's tier was upgraded. The caller already has an API key (they authenticated on the original POST /auth/checkout), so this response just confirms the subscription update. No key is returned.

4. Portal opened

{
  "status": "portal_opened",
  "dashboard_url": "https://dashboard.boringmarketing.com"
}

Terminal state for sessions where the "checkout URL" was actually a billing portal URL. This happens whenever the email already has an active subscription — both authenticated callers (who passed a matching X-API-Key) and anonymous callers whose email maps to an active account get a billing portal session instead of a fresh checkout. Billing portal sessions have no webhook-completable state, so this is a one-shot "stop polling" signal on the first call.

5. Session not found (404)

There is no expired status. If a session has been reaped by the checkout session reaper (expired sessions are cleaned up on each API process startup) or the session_id is otherwise unknown, the endpoint responds with:

{ "detail": "Checkout session not found." }

with HTTP status 404. Start a new session with POST /auth/checkout.

Example — anonymous flow

SESSION_ID="bmc_k7f3..."

# Poll until completed
while true; do
  RESP=$(curl -sw "\n%{http_code}" "https://api.boringmarketing.com/auth/checkout/$SESSION_ID/status")
  BODY=$(echo "$RESP" | head -n1)
  CODE=$(echo "$RESP" | tail -n1)
  if [ "$CODE" = "404" ]; then
    echo "Session not found (reaped or invalid) — restart with POST /auth/checkout"
    exit 1
  fi
  STATUS=$(echo "$BODY" | python3 -c "import sys,json; print(json.load(sys.stdin)['status'])")
  if [ "$STATUS" = "completed" ]; then
    DASHBOARD_URL=$(echo "$BODY" | python3 -c "import sys,json; print(json.load(sys.stdin)['dashboard_url'])")
    echo "Payment confirmed. Sign into $DASHBOARD_URL with a magic link to retrieve your API key."
    break
  fi
  sleep 5
done
Checkout Status — Boring Marketing