Skip to content
Metric VaultHelp Center
Open app

Customer lookup and billing

Look up one customer, read their plan, usage, billing, channels, seats and profile, and run every account action with its exact database effect.

Last updated 2026-08-11

Summary#

The Customers screen is the single-account view. Enter an email address and you get the resolved plan, this month's usage against quota, the admin actions already taken on that account, a read-only Stripe billing panel, connected social channels and team seats. An owner can also change the plan, reset usage, refund credits, suspend or reactivate the account and remove a seat. Every one of those writes to the audit log.

Purpose#

Most support tickets are about one person: they cannot run a tool, their plan is wrong, they were charged and nothing changed, or they want a seat back. Before this screen existed those questions needed a database query. Now they need an email address. The screen deliberately shows resolved values, the ones the platform will actually enforce, rather than raw table contents, so what you read is what the customer experiences.

Requirements#

  • An active admin identity. See Getting admin access.
  • The customer's email address. Partial search is not supported here; use the Subscribers directory to find the address first.
  • MONITOR_DB bound.
  • For live subscription data, STRIPE_SECRET_KEY set on the environment. Without it the billing panel reads Stripe is not configured on this environment.

Permissions#

ActionRole needed
Look up a customer and read every paneladmin
Set plan, reset usage, refund credits, grant credits, suspend, reactivate, remove a seatowner
Revoke a connected social channelowner
Set a display name, upload a photo, remove a photoadmin

Mutations by an admin return 403 {"error":"Only an owner can manage customers."}, or 403 {"error":"Only an owner can disconnect a channel."} for a channel revoke. The billing panel is admin-gated and read-only for everyone.

The three profile actions are the exception, and deliberately so: they live on their own endpoint and any active admin may use them. Fixing a customer's name or clearing a photo they cannot clear themselves is support-desk work, not account control, so it is not worth escalating to an owner. They are audited like everything else.

Admin console → Operations → Customers

You can also reach it pre-filled by pressing View on any row of the Subscribers directory.

Step-by-Step Guide#

Look up an account#

  1. Select Customers in the Operations group.
  2. Type the address into the field labelled customer@example.com in the Look up a customer card.
  3. Press Load, or press Enter in the field. An empty field returns Enter an email.
  4. Three calls fire together: the account summary, the audit log filtered to that address with a limit of 25, and the billing read.
Screenshot
The Customers screen after a lookup, showing the Plan, Used this month and Breakdown tiles above the Actions card.

Read the result#

PanelWhat it tells you
PlanThe resolved plan, plus a green active or red suspended badge
Used this month<used> / <quota> where used is AI runs plus tool runs, and <remaining> remaining
BreakdownAI: and Tools: counts and the month key in YYYY-MM
ActionsThe owner-only mutation row
Recent actions on this customerThe audit log filtered to this address. Empty reads No recorded admin actions on this customer.
BillingPlan source and, when Stripe is configured, the live subscription
Connected channelsOne row per social connection with a Revoke button. Empty reads None connected.
Team members(used / cap seats) in the heading, one row per membership with active or pending, and a Remove button. Over the cap the heading turns red and appends — over limit
ProfileThe customer's photo, or their initials when they have none, and their display name in an editable field

The quota comes from the plan: Free 0, Starter 100, Pro 500, Agency 2,000, Enterprise 10,000, Unlimited 1,000,000,000. The seat cap counts invited members only, never the owner: Free and Starter 0, Pro 4, Agency 14, Enterprise and Unlimited 100,000.

Important

Important: The plan shown is the resolved plan, which is not always the stored one. Addresses in the worker's DEV_UNLIMITED_EMAILS list always resolve to unlimited and bypass every gate, and addresses in FORCE_FREE_EMAILS always resolve to free. Setting a plan for one of those writes the user_plans row successfully and changes nothing, because the code override wins.

Change the plan#

  1. Pick a value from the plan select: free, starter, pro, agency, enterprise or unlimited.
  2. Press Set plan.

This writes user_plans with set_by = 'admin' and notes = 'admin panel', which is what makes the billing panel show the Manual (admin) source badge afterwards. An unrecognized plan returns 400 {"error":"Unknown plan."} and a failed write returns 400 {"error":"Could not set plan."}.

Warning

Warning: Setting a plan here does not touch Stripe. If the customer has a live subscription, the next Stripe event can overwrite what you set. Use this for comps and corrections, and fix real subscription problems in Stripe.

Reset monthly usage#

Press Reset monthly usage. This sets ai_runs and tool_runs to zero on the current month's row only. Previous months, the per-tool credit breakdown and the AI recommendation counter are untouched. There is no undo: the previous counts are overwritten, not archived. The audit entry records the month key.

Refund credits#

  1. Type a whole number into the field labelled credits.
  2. Press Refund. A missing or non-positive value returns the client message Enter a positive credit amount to refund.

The amount is floored and clamped between 1 and 1,000,000. The refund reduces recorded usage for the current month rather than issuing money: AI runs are reduced first, and any remainder comes off tool runs, with both floored at zero.

Grant extra credits#

  1. Type a whole number into the second field labelled credits.
  2. Press Grant. A missing or non-positive value returns the client message Enter a positive credit amount to grant.

Where Refund can only bring recorded usage back down to zero, Grant raises the customer's quota itself: the amount is added on top of the plan quota for the current calendar month, shows in the Used this month card as includes <n> bonus, and the customer's own dashboard shows the raised total. Repeated grants accumulate. The bonus expires when the month rolls over; to revoke it sooner, delete the quota_bonus:<email>:<month> key on the Config screen. Audited as customer.grant_credits with the amount. Refunding more than the customer has used simply zeroes both counters. Nothing is sent to Stripe and nothing is refunded to a card.

Suspend and reactivate#

Suspend writes the configuration key suspended:<email> with the value 1. Reactivate deletes that key. Both bust the 60-second configuration cache, so the change is effective immediately rather than up to a minute later.

A suspended customer is blocked at two gates with 403 {"error":"This account is suspended. Please contact support.","code":"account_suspended"}: the AI quota gate and the AI recommendation gate. The screen's own footnote says it plainly: Suspend blocks the customer from running paid AI tools. Free, zero-credit tools and the rest of the dashboard remain reachable. Suspension is also what drives the suspended badge here and the status column in the subscriber directory.

Suspension is fully reversible and sends no notification. The customer learns about it the next time they press a paid tool.

Remove a seat#

Press Remove on a team row. A native confirm asks Remove <member> from <owner>'s team?. Confirming deletes the membership and the page reloads with Removed <member>. The removed teammate loses access to that workspace at once. Re-adding them requires a fresh invitation from the workspace owner; the console cannot invite.

Change a display name or photo#

The Profile card shows exactly what the customer sees on their own Account screen: the same photo in the same circle, and the same display name.

  1. Edit the Display name field and press Save name. An empty field is allowed and clears the name.
  2. Press Upload photo to pick an image. It is resized to 512 pixels in your browser before it is sent, so a photo off a phone will not hit the 2 MB cap. Accepted formats are PNG, JPG, WEBP and GIF.
  3. Press Remove photo to take it down. A native confirm asks Remove this customer's profile photo?. The button only appears when the customer has a photo.

Each of the three reloads the lookup so you are reading the saved state, not what you typed. The customer sees the change the next time their Account screen opens; no notification is sent.

When the environment has no image storage bound, Upload photo is replaced by Photo storage is not configured on this environment. and the display name can still be edited.

Revoke a connected channel#

Press Revoke on a channel row. The confirm reads Revoke <platform> for <email>? They will have to reconnect it. Confirming deletes the stored connection, including its tokens, and reports Revoked <platform> (<n>). The customer must reconnect the platform themselves.

Read the billing panel#

The panel first shows the plan and where it came from: a Stripe badge, a Manual (admin) badge or Default, followed by how long ago it was set and any notes. Then one of these:

What you seeMeaning
Stripe is not configured on this environment.STRIPE_SECRET_KEY is not set. Nothing was queried
Could not reach Stripe: <error>The Stripe call failed. The plan line above is still valid
No Stripe customer found for this email.Stripe has no customer with that address
Stripe customer found, but no subscription on record.A customer exists with no subscriptions
Subscription <status> plus Tier <tier> · $NN.NN USD / month and Renews <date>A live subscription

The lookup takes the first subscription whose status is active, trialing or past_due, and otherwise the first subscription it finds. A cancels at period end chip appears when the subscription is set to lapse. When Stripe does not return a unit amount the line reads amount not returned by Stripe rather than inventing a figure.

Screenshot
The Billing card showing the plan source badge, an active subscription with tier and renewal date, below it the Connected channels and Team members cards.
Note

Note: The billing panel is read-only by design. There is no cancel, refund, plan-change or customer-portal control anywhere in the console. Subscription changes happen in Stripe. See What the admin console cannot do yet.

What gets recorded#

Every mutation writes one row to the audit log with your email as the actor and the customer's email as the target.

ActionAudit actionMeta
Set plancustomer.set_planthe plan
Reset monthly usagecustomer.reset_usagethe month key
Refund creditscustomer.refund_creditsthe amount
Suspendcustomer.suspendnone
Reactivatecustomer.reactivatenone
Remove a seatcustomer.remove_seatthe member's email
Save a display namecustomer.set_display_namethe saved name, or (cleared)
Upload a photocustomer.set_avatarnone
Remove a photocustomer.remove_avatarremoved, or none when there was no photo
Revoke a channelsocial.disconnectthe platform, and the account id when present

Those rows are exactly what the Recent actions on this customer panel reads back. See Audit log.

Troubleshooting#

SymptomLikely causeFix
A valid email is required.The field is blank or has no @Retype the full address
No action buttons under the tilesYour role is adminAn owner performs the change
A plan change appears to work but the customer still hits the old limitThe address is in DEV_UNLIMITED_EMAILS or FORCE_FREE_EMAILS, or their browser is holding a cached planCheck the override lists; ask the customer to reload
Refund reported success but usage did not moveThere is no usage_counters row for the current month, so nothing was updated. Every action returns success regardless of rows changedConfirm with the tiles after the reload
Usage shows zero for an active customerYou are looking at the current calendar month in UTC and their activity was last monthCheck the Run Log for the full history
Seats show over limitThe plan was downgraded while members were attachedRemove seats until the count fits, or restore the plan
Billing shows Could not reach Stripe:A Stripe API error or an expired keyVerify STRIPE_SECRET_KEY; the plan line is unaffected
Suspension seems not to applyThe customer is in the dev-unlimited list, which returns before the suspension checkNothing to fix here; those addresses bypass every gate
That image is larger than 2 MB.The image was still over the cap after resizing, usually a large animated GIFUse a still image
That file is not a PNG, JPG, WEBP or GIF image.The file's contents are not an image, whatever its name saysPick a real image file
The customer says their photo has not changedTheir browser is holding the old pageAsk them to reload; the photo address changes on every upload, so there is no stale cache to clear

FAQs#

Does the customer get an email when I suspend, refund or change their plan? No. The console sends no notifications at all. Contact them yourself.

Can I undo a usage reset? No. The counters are overwritten. Refunding credits has the same shape and is also not reversible, though you can set the numbers back by refunding or letting usage accrue again.

Can I delete a customer's account or export their data? Not from the console. Neither endpoint exists. See What the admin console cannot do yet.

Can I log in as a customer to reproduce a bug? No. There is no impersonation. Use the Run Log to see exactly what they ran and the error log for what failed.

How current is the usage figure? It is read live from usage_counters on every lookup. Suspension state is read through a configuration cache that is 60 seconds old at most, and suspend and reactivate clear that cache immediately.

Why does the plan source say Default? Because there is no user_plans row at all, so the customer resolves to the built-in default. Setting any plan creates the row and switches the badge to Manual (admin).

See also

Was this article helpful?