---
title: "Current plan with all gate flags consumed by useMePlan hook"
method: GET
path: "/api/me/plan"
tags: ["me"]
---

# Current plan with all gate flags consumed by useMePlan hook

`GET /api/me/plan`

## Request

- Base URL: `https://api.signalraven.ai`
- URL: `https://api.signalraven.ai/api/me/plan`
- Auth: none declared

Returns the customer's plan slug, economics, caps, and feature flags (signalStacking, icpEditing, paygEnabled, etc.). Includes derived isInternal flag + stripeCustomerId for portal Stripe-management UX gating. 5-min Cache-Control private.

## Response `200`

Current plan

- MePlan
  - `slug` 'trial' | 'trial_standard' | 'solo' | 'pro' | 'scale' | 'internal', required: Plan slug
  - `name` string, required
  - `monthlyPriceCents` integer, required: 0 for Trial + Internal
  - `creditAllotment` integer, required: Monthly bucket size in credits
  - `maxSources` integer, nullable, required: null = unlimited (Scale + Internal)
  - `maxDestinations` integer, nullable, required: null = unlimited
  - `maxUsers` integer, nullable, required: Seat cap. null = unlimited (Scale + Internal). Read by getSeatCap() — null coerces to Infinity portal-side
  - `signalStacking` boolean, required: Enables Pro+ signal-stacking feature (urgency bumps from history)
  - `icpEditing` 'basic' | 'advanced', required: Basic = simple ICP form. Advanced (Scale + Internal) = full dimension editing
  - `paygEnabled` boolean, required: Whether the customer can buy add-on credit packs
  - `addOnRatePerCredit` number, nullable, required: $/credit for PAYG purchases. NULL when paygEnabled=false
  - `isInternal` boolean, required: Derived as slug === "internal"; portal hides Stripe-only UX when true
  - `stripeCustomerId` string, nullable, required: null until first paid upgrade. Manage-subscription button only shown when set
  - `scheduledDowngrade` object, nullable, required: Non-null while a downgrade is scheduled for next renewal. Read from customer.metadata.scheduledDowngrade — populated by the subscription.updated webhook handler.
    - `effectiveAt` string, date-time, required: ISO timestamp when the downgrade takes effect (= subscription current_period_end)
    - `previousPlanSlug` string, required
    - `previousPlanName` string, required
    - `newPlanSlug` string, required
    - `newPlanName` string, required
    - `newMaxSources` integer, nullable, required
    - `newMaxDestinations` integer, nullable, required
    - `newMaxUsers` integer, nullable, required
    - `capChangesPreview` string, required: Plain-English summary of what will exceed the new plan caps at effectiveAt (e.g. "10 sources and 1 destination will exceed your new plan's caps. Existing items keep running, but you won't be able to add new ones until you're under the limit."). Per design §3.4 soft enforcement: no auto-deactivation occurs. Returns "You are already within the new plan caps." when nothing exceeds.
    - `notifiedAt` string, date-time, required: ISO timestamp when the email + bell-icon notification fired. Banner survives a refresh; the email/bell fire once.
    - `targetType` 'trial' | 'paid': "trial" = cancel-to-trial flow (subscription terminates and customer returns to Trial). "paid" = paid-to-paid downgrade (subscription continues at the new lower price). Portal renders different banner copy for each variant.
    - `targetPriceId` string, nullable: Future Stripe Price ID the subscription will move to at effectiveAt. Null for cancel-to-trial (Trial has no Stripe Price). Webhook un-cancel branch compares this to the current price to distinguish "downgrade completed" from "scheduled change cleared without reaching new price".
    - `scheduleId` string, nullable: Stripe Subscription Schedule ID when the change was scheduled via the SubscriptionSchedules API (paid-to-paid downgrades). Null for cancel_at_period_end-based changes (cancel-to-trial). Used by the undo endpoint to release the schedule cleanly.

## Other responses

- `401`: Not authenticated
- `403`: Customer not active
- `500`: Customer missing plan_id (migration anomaly)

---

[API](https://skmtc.dev/signalraven/apis/zygnal-api.md) · [All operations](https://skmtc.dev/signalraven/apis/zygnal-api/llms.txt) · [OpenAPI document](https://skmtc.dev/signalraven/apis/zygnal-api/revisions/36e1d9b9d604?raw)
