Skip to content
Coritan Docs

Organization API: Customers: Staff

The 32 Organization API operations for staff.

View as Markdown

Part of Customers.

Method Path Summary
POST /api/v1/orgs/{org_slug}/staff/community/chat/customers/{customer_id}/ban Staff chat ban
POST /api/v1/orgs/{org_slug}/staff/community/chat/customers/{customer_id}/mute Stop a customer posting in the chat (and the forum) for minutes
POST /api/v1/orgs/{org_slug}/staff/community/chat/customers/{customer_id}/unban Lift a customer's chat ban, and the networks it covered
GET /api/v1/orgs/{org_slug}/staff/customers Directory for this brand, separate from the mixed desk search
POST /api/v1/orgs/{org_slug}/staff/customers An account for someone who ordered by phone or email
POST /api/v1/orgs/{org_slug}/staff/customers/bulk Staff customers bulk
GET /api/v1/orgs/{org_slug}/staff/customers/export.csv The directory as it is filtered, as a CSV
GET /api/v1/orgs/{org_slug}/staff/customers/stats Staff customers stats
GET /api/v1/orgs/{org_slug}/staff/customers/tags Every label in use on this brand, with how many customers carry it
GET /api/v1/orgs/{org_slug}/staff/customers/{customer_id} Staff customer hub
PATCH /api/v1/orgs/{org_slug}/staff/customers/{customer_id} Fix the profile (support), or change the account's standing (admin)
GET /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/activity Staff customer activity
POST /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/chat-mute Silence a handle in community chat and the forum for a while, or lift it
POST /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/close Staff close customer
POST /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/credit Staff add credit
GET /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/credit-ledger The customer's wallet, newest entry first
GET /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/data-export Everything held about the customer, as one JSON file, for a privacy request
GET /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/emails Staff customer emails
POST /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/impersonate Staff impersonate customer
POST /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/legacy-move/complete Ask the brand's previous website again to confirm that an account moved
POST /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/mark-verified Vouch for an address the customer proved another way (a call, a ticket from that inbox)
GET /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/notes List customer notes
POST /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/notes Add customer note
GET /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/oauth-history Staff customer OAuth history
GET /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/payment-methods Staff customer payment methods
GET /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/related Staff customer related
POST /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/resend-verification Staff resend verification
POST /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/reset-mfa For a customer who lost their phone: remove their second factor and end their sessions
POST /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/reset-password Staff reset customer password
POST /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/revoke-sessions Staff revoke customer sessions
GET /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/sessions Staff customer sessions
PUT /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/tags Staff set customer tags

POST /api/v1/orgs/{org_slug}/staff/community/chat/customers/{customer_id}/ban

Close the chat to a customer's account, with a reason the customer reads when they try to post, for days (null is no end). include_addresses also closes it to the networks the account posted from in the last 30 days, so a new account on the same network cannot post either; hide_recent hides the account's messages from the last 24 hours. A second ban replaces the first.

Name In Type Required
customer_id path integer yes
org_slug path string yes

application/json (required)

Field Type Required
reason string yes
days integer or null no
include_addresses boolean no
hide_recent boolean no
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Stop a customer posting in the chat (and the forum) for minutes

Section titled Stop a customer posting in the chat (and the forum) for minutes

POST /api/v1/orgs/{org_slug}/staff/community/chat/customers/{customer_id}/mute

Stop a customer posting in the chat (and the forum) for minutes. Tier 1 and Tier 2 support mute for up to 7 days and never shorten a longer mute already running (kept_longer_mute); Tier 3 sets any length up to a year and lifts a mute with minutes: 0.

Name In Type Required
customer_id path integer yes
org_slug path string yes

application/json (required)

Field Type Required
minutes integer yes
reason string or null no
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Lift a customer's chat ban, and the networks it covered

Section titled Lift a customer's chat ban, and the networks it covered

POST /api/v1/orgs/{org_slug}/staff/community/chat/customers/{customer_id}/unban

Lift a customer's chat ban, and the networks it covered.

Name In Type Required
customer_id path integer yes
org_slug path string yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Directory for this brand, separate from the mixed desk search

Section titled Directory for this brand, separate from the mixed desk search

GET /api/v1/orgs/{org_slug}/staff/customers

Directory for this brand, separate from the mixed desk search.

status_filter is an account status or one of CUSTOMER_BUCKETS (unverified, new_7d, paying, free). counts carries one count per status and per bucket. unverified is accounts whose email was never verified, new_7d signups inside the last seven days, paying accounts with at least one non-free service and free the rest. Every count is under the audience the request carries, and none is narrowed by q, tag or the filter itself, so the tiles keep reading as the whole directory while the list is narrowed.

The accounts and the rows are always current. Counting the paying accounts of a large brand takes a while, so paying and free can trail a new order by up to a minute, and the first request after a quiet spell can show them a few minutes old. So can total when the request has no filter but the audience and a status word, and the audience is paid or free or the word is paying or free. Every other total and every other number is current, and a bulk run counts again when it starts.

The list is paying accounts first, then newest sign-up first inside each group, with the account ID as the last tiebreak so a page never repeats or skips an account.

email_domain, created_after, created_before, discord and pattern_id narrow the list and total further. total is the number of accounts a customers bulk run (POST /staff/abuse/bulk-runs) with the same filter acts on, up to the minute noted above. A date that is not ISO 8601, a discord word other than linked or unlinked and an email domain that is not one answer 422; a pattern_id that is not one of this brand's patterns answers 404. Each row carries discord: whether a Discord account is linked and how many days old it is.

segment narrows the list and total to one customer group (vip, at_risk, one_time, past_due, no_server or new; GET /staff/customers/stats has the definitions and the count of each). Any other word answers 422 and names the allowed ones.

Placeholders for forum authors moved from the brand's previous platform (status unclaimed) are not accounts. The list, total and every count in counts leave them out, and a status_filter of unclaimed matches nothing. GET /staff/customers/{customer_id} still opens one by its ID.

Name In Type Required Description
org_slug path string yes
q query string or null no Email, name, handle or company (* is a wildcard), an account ID, a sign-up IP address (exactly), or a Discord username or ID. A word with an @ is matched against email addresses only.
status_filter query string or null no
tag query string or null no
audience query string or null no
limit query integer no Default: 50.
offset query integer no Default: 0.
email_domain query string or null no Accounts whose email address is at this domain or one of its subdomains, such as example.com.
created_after query string or null no Signed up on or after this day (2026-09-27) or moment (2026-09-27T14:00:00Z).
created_before query string or null no Signed up before this moment, or on or before this day when it is a bare date.
discord query string or null no linked: accounts with a Discord account linked. unlinked: accounts without one.
pattern_id query integer or null no The accounts of one of this brand's abuse patterns. For an email domain pattern that is the accounts on the domain and its subdomains that signed up no earlier than 30 days before the pattern was first seen; for the other kinds, the accounts the pattern recorded.
segment query string or null no A customer group: vip (lifetime spend in the top 5 percent and at least five times the median payment), at_risk (two or more paid invoices, none in the last 60 to 180 days), one_time (exactly one paid invoice, more than 30 days ago), past_due (an invoice past its due date), no_server (no active service) or new (signed up in the last 30 days).
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

An account for someone who ordered by phone or email

Section titled An account for someone who ordered by phone or email

POST /api/v1/orgs/{org_slug}/staff/customers

An account for someone who ordered by phone or email. No password is set here; the customer gets a link to choose their own, so staff never know it.

Name In Type Required
org_slug path string yes

application/json (required)

Field Type Required
email string (email) yes
first_name string or null no
last_name string or null no
company string or null no
phone string or null no
currency string or null no
send_setup_email boolean no
Status Meaning
201 Success.
422 The request is not valid. detail lists each problem.

POST /api/v1/orgs/{org_slug}/staff/customers/bulk

Suspend, unsuspend or terminate every order a selection of customers has, pause the accounts, or ban them outright.

The fleet's bulk route acts on servers picked one by one; this one is for the search that turned up a dozen accounts with the same email pattern. Pausing suspends the account and its running orders until someone unsuspends it. Same gate: support may suspend and unsuspend; anything that ends an order or changes an account's standing (terminate, ban, pause, a deletion date) is an org admin who has stepped up in the last ten minutes. For more than 100 accounts, start a bulk run (POST /staff/abuse/bulk-runs). A placeholder for a moved forum author is skipped and reported, like a closed account.

Name In Type Required
org_slug path string yes

application/json (required)

Field Type Required
customer_ids array of integer yes
action string yes
reason string yes
delete_after_days integer or null no
open_ticket boolean no
notify_customer boolean no
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

The directory as it is filtered, as a CSV

Section titled The directory as it is filtered, as a CSV

GET /api/v1/orgs/{org_slug}/staff/customers/export.csv

The directory as it is filtered, as a CSV. Billing roles only: an export is every customer's contact details in one file. status_filter takes the same values as the directory, the tile buckets included, and placeholders for moved forum authors are left out as they are there.

The file holds the current accounts, paying accounts first and the newest sign-up first inside each group, and stops at 20,000 rows. Narrow the filter to export a larger brand in parts.

Name In Type Required
org_slug path string yes
q query string or null no
status_filter query string or null no
tag query string or null no
audience query string or null no
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

GET /api/v1/orgs/{org_slug}/staff/customers/stats

How many accounts are in each customer group, for the tiles above the directory, under the audience the request carries.

segments holds one count per word of the directory's segment filter (vip, at_risk, one_time, past_due, no_server, new), and definitions says what each word means. Each count comes from the clause the list filters with, so a tile's number is the total of GET /staff/customers?segment=<word> under the same audience. all is every account in the audience; placeholders for moved forum authors are left out of every count.

The counts cover the whole brand. They are normally under a minute old, and the first request after a quiet spell can show numbers a few minutes old. The vip count uses spending cutoffs that are worked out every ten minutes. The free counts are the all counts less the paid ones.

Name In Type Required
org_slug path string yes
audience query string or null no
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Every label in use on this brand, with how many customers carry it

Section titled Every label in use on this brand, with how many customers carry it

GET /api/v1/orgs/{org_slug}/staff/customers/tags

Every label in use on this brand, with how many customers carry it.

Like the directory the labels filter, it counts accounts only. A change made through PUT /staff/customers/{customer_id}/tags shows here within seconds. A label that changes any other way (an account removed, or turned into a placeholder) can take up to five minutes to show, and the first request after a quiet spell can show the earlier list.

Name In Type Required
org_slug path string yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

GET /api/v1/orgs/{org_slug}/staff/customers/{customer_id}

One customer's record: the account (with display_name), their services, invoices, tickets and staff notes. Each ticket carries its department and assigned_agent_name (the team member's first and last name, else their email; null when unassigned), as the inbox shows them. It also opens a placeholder for a moved forum author (status is unclaimed), which no list shows.

legacy_move is null unless the account moved in from the brand's previous website. Then it holds the old account's old_user_id and old_username (null once the account is closed), how it moved (account is new, placeholder, merge_automatic or merge_sign_in, and merged says whether it joined an account that was already here), moved_at, the wallet credit (credited_usd and its breakdown), how many saved cards came with it (cards_error says why none could be read), the old sign-in providers, whether the previous website confirmed the move (acknowledged and acknowledged_at) and any drift it reported. connections names the sign-in providers whose link came across, and connections_skipped lists the links the move left alone, each with its provider and a reason: linked_elsewhere (another account here already uses that provider account), provider_already_connected or account_not_active. A linked_elsewhere item also carries held_by_customer_id, the customer who holds it, and held_by_empty_account: true when that customer looked empty when the move ran (no transactions, no credit, no servers and not a moved account), which usually means signing in with that provider made a second account for the same person. Both keys are left out when nobody held the link, and on records from before the move named the holder. alerts lists up to 20, newest first: late_money for money that reached the old account after the move, chargeback for a dispute on an old charge, drift for a balance that changed after the move, and not_pending when the previous website did not have the old account waiting to move. servers lists the free servers that moved with the account, from the brand's free-server runs, newest run first and at most 50: name, status (waiting, working, done, failed, released or cancelled), phase, reason (a word, never error text), new_server_uuid, join_address, backups_imported, backups_failed and finished_at. It is empty for an account that moved on its own. POST /staff/customers/{customer_id}/legacy-move/complete asks the previous website again while acknowledged is false.

discord is the account's Discord link: username, discord_id, when the Discord account was made (account_created_at, read off its ID) and its age_days, when it was linked (linked_at), and whether it is old enough for a free order from a VPN or hosting network (meets_age_rule; qualifies_on says when a newer one will be). With no link it reads linked: false and every other field is null. GET /staff/customers/{customer_id}/oauth-history lists every link, move and refused attempt.

customer.lifetime_paid is every payment the customer made, and customer.lifetime_paid_by_currency the same payments per currency, as {"USD": "125.00"}: an amount in one currency is never added to another's. customer.abuse_patterns lists the open or blocked abuse patterns the account is part of, as {id, kind, value, status}, newest activity first and at most 20; it is empty when the account is in none.

attribution is how the account was made and where its owner came from, or null for an account staff made or one made before attribution was recorded. method is email, code, checkout or the social provider. It holds the first and last touch (each with its channel as {key, label}, the ad network and the UTM fields, or null when no visit was seen), the click_ids with their ad network, device_type, country_code, the consent the visitor had, and heard_about: the answer on the customer's first order that has one.

Name In Type Required
customer_id path integer yes
org_slug path string yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Fix the profile (support), or change the account's standing (admin)

Section titled Fix the profile (support), or change the account's standing (admin)

PATCH /api/v1/orgs/{org_slug}/staff/customers/{customer_id}

Fix the profile (support), or change the account's standing (admin).

A new email address is unverified again and gets a fresh verification mail: the old inbox proved nothing about the new one. The old address is told of the change (old_address_notified in the answer), so an owner whose account was taken over, or whose address was changed on a forged request, hears of it. Leaving active ends every session the customer has, so a ban is not decorative. A placeholder for a moved forum author answers 409 to a status or a new email, and takes the other fields.

Name In Type Required
customer_id path integer yes
org_slug path string yes

application/json (required)

Field Type Required
email string (email) or null no
first_name string or null no
last_name string or null no
company string or null no
phone string or null no
status string or null no
reason string or null no
currency string or null no
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

GET /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/activity

One timeline, newest first: what staff did to the account, what the customer did, and what billing and support recorded.

The timeline is always current and holds the newest limit events (up to 300). Each kind of event is read separately before they are merged: the account's log entries up to limit, sign-ins and support sessions up to 30 or limit if that is smaller, and invoices, payments, transactions and tickets up to 50 each. A busy account can therefore show fewer old events of one kind than it has.

Name In Type Required Description
customer_id path integer yes
org_slug path string yes
limit query integer no Default: 100.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Silence a handle in community chat and the forum for a while, or lift it

Section titled Silence a handle in community chat and the forum for a while, or lift it

POST /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/chat-mute

Silence a handle in community chat and the forum for a while, or lift it.

Name In Type Required
customer_id path integer yes
org_slug path string yes

application/json

Field Type Required
minutes integer or null no
reason string or null no
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

POST /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/close

Close and anonymise, with the same guard the customer's own close has: no active services, no unpaid invoices. A placeholder for a moved forum author answers 409 with the code placeholder, because closing would make it a closed account.

Name In Type Required
customer_id path integer yes
org_slug path string yes

application/json (required)

Field Type Required
reason string yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

POST /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/credit

Name In Type Required
customer_id path integer yes
org_slug path string yes

application/json (required)

Field Type Required
amount number or string yes
description string no
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

The customer's wallet, newest entry first

Section titled The customer's wallet, newest entry first

GET /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/credit-ledger

The customer's wallet, newest entry first. balance and every amount are in currency, the wallet's (US dollars, whatever the customer is billed in), which credit_currency repeats under the name every other answer carrying a wallet balance uses. Each entry names the invoice it settled or came back from by invoice_number and the service it belongs to by service_hostname, or None when it has none or the record is gone.

Name In Type Required Description
customer_id path integer yes
org_slug path string yes
limit query integer no Default: 50.
offset query integer no Default: 0.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Everything held about the customer, as one JSON file, for a privacy request

Section titled Everything held about the customer, as one JSON file, for a privacy request

GET /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/data-export

Everything held about the customer, as one JSON file, for a privacy request.

The privacy policy promises a copy of their data to anyone who asks; this is the copy. Admin and stepped-up like closing the account, because it is the whole person in one download; rate-limited with the other exports; and audited before the document is built, so the document itself records that it was produced, by whom, and when.

Name In Type Required
customer_id path integer yes
org_slug path string yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

GET /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/emails

Every transactional email the brand sent this customer and whether it went, so "we emailed your server details on this date" can be shown rather than asserted. Each carries tracking: {opened, opens, clicked, clicks, first_open_at, first_click_at, maileroo} for a message whose opens and clicks are tracked, or null.

Name In Type Required Description
customer_id path integer yes
org_slug path string yes
limit query integer no Default: 50.
offset query integer no Default: 0.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

POST /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/impersonate

Open a support session as one of the organization's customers, from the staff console or the coritan.com dashboard.

The answer's portal_url opens the storefront signed in as the customer (/auth/callback on the custom domain, else on the commerce store's storefront address). read_only is Tier 3 support and above; servers and full need an owner or admin and a step-up (403 reauth_required), and full a reason of at least 5 characters. The session lasts 30 minutes and cannot be extended. 409 when the customer is not active, or when the organization has no storefront to open it on, in which case nothing is opened. 20 an hour per member.

Name In Type Required
customer_id path integer yes
org_slug path string yes

application/json

Field Type Required Description
mode string or null no
elevated boolean no
reason string or null no
next string or null no
origin string or null no staff (the default) or dashboard: where the session was opened, so ending it goes back the right way.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Ask the brand's previous website again to confirm that an account moved

Section titled Ask the brand's previous website again to confirm that an account moved

POST /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/legacy-move/complete

Ask the brand's previous website again to confirm that an account moved.

When an account moves in, we tell the previous website, which then zeroes the old balances and marks the old account as moved. If that message was lost, legacy_move.acknowledged on GET /staff/customers/{customer_id} stays false, and the old account stays locked with its balance. This sends the message again, with what the move credited, and records the answer: acknowledged and acknowledged_at once the previous website has confirmed the move, and drift when it reports a balance that changed after the move (the account also gets a drift alert). Every attempt that reaches the previous website goes in the audit log as customer.legacy_move_completed.

Needs the owner, admin or billing role. Refusals answer with detail.code and detail.message: 404 for a customer this organization does not have; 409 not_moved for an account that did not move in, already_acknowledged when the previous website has already confirmed the move, and link_off while the organization's link to its previous website is off; 503 old_site_unavailable when the previous website did not confirm the move, which can be tried again later.

Name In Type Required
customer_id path integer yes
org_slug path string yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Vouch for an address the customer proved another way (a call, a ticket from that inbox)

Section titled Vouch for an address the customer proved another way (a call, a ticket from that inbox)

POST /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/mark-verified

Vouch for an address the customer proved another way (a call, a ticket from that inbox). Admin only, and on the record. A placeholder for a moved forum author has no address to vouch for and answers 409.

Vouching is a first proof, so it settles what the customer's own first proof settles (prove_address): the pending confirmation link goes, an authenticator on an account with no password goes, subuser invites apply, and the sign-in links an account move carried while the address was unproven are removed. The customer then signs in with their email and links the provider again. It does not end sessions, which the customer's own proof by email does: staff did not ask for that, the customer may be using the account right now, and the Sessions list ends them on request. The answer is the same when the address was already verified.

Name In Type Required
customer_id path integer yes
org_slug path string yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

GET /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/notes

Name In Type Required Description
customer_id path integer yes
org_slug path string yes
limit query integer no Default: 50.
offset query integer no Default: 0.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

POST /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/notes

Name In Type Required
customer_id path integer yes
org_slug path string yes

application/json (required)

Field Type Required
body string yes
Status Meaning
201 Success.
422 The request is not valid. detail lists each problem.

GET /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/oauth-history

Every time a sign-in account (Discord, GitHub and the rest) was linked to, moved to, unlinked from or refused on this customer, newest first.

The list also holds the events of every Discord account this customer has held, so it names each other account on the brand that linked or tried the same one. Each event carries event (linked, moved, unlinked or refused), a reason (for an unlink customer, replaced or account_closed; for a refusal taken or move_limit), the Discord discord_id, username and account_created_at, the customer who made it, the previous_customer who held it and the ip it came from. Tier 3 support and up; another brand's customer answers 404.

Name In Type Required Description
customer_id path integer yes
org_slug path string yes
limit query integer no At most this many events, newest first. Default: 50.
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Staff customer payment methods

Section titled Staff customer payment methods

GET /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/payment-methods

What the customer has on file, as the customer sees it: a label, a brand, the last four digits, the expiry. The gateway token never leaves the row.

Name In Type Required
customer_id path integer yes
org_slug path string yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

GET /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/related

Other customers on this brand that share a sign-up IP, a sign-up fingerprint, a phone number or a recent session address with this one.

Signals, not verdicts: a household shares an IP. Each match says which signal it came from so the person reading can weigh it.

Name In Type Required
customer_id path integer yes
org_slug path string yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

POST /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/resend-verification

Name In Type Required
customer_id path integer yes
org_slug path string yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

For a customer who lost their phone: remove their second factor and end their sessions

Section titled For a customer who lost their phone: remove their second factor and end their sessions

POST /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/reset-mfa

For a customer who lost their phone: remove their second factor and end their sessions. They sign in again and, if the brand requires it, enrol.

Name In Type Required
customer_id path integer yes
org_slug path string yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

POST /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/reset-password

Give the customer a new password and end their sessions, or, without password, email them the storefront's reset link (link_sent).

Name In Type Required
customer_id path integer yes
org_slug path string yes

application/json

Field Type Required
password string or null no
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

Staff revoke customer sessions

Section titled Staff revoke customer sessions

POST /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/revoke-sessions

Name In Type Required
customer_id path integer yes
org_slug path string yes

application/json

Field Type Required
token_id integer or null no
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

GET /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/sessions

Name In Type Required
customer_id path integer yes
org_slug path string yes
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.

PUT /api/v1/orgs/{org_slug}/staff/customers/{customer_id}/tags

Name In Type Required
customer_id path integer yes
org_slug path string yes

application/json (required)

Field Type Required
tags array of string no
Status Meaning
200 Success.
422 The request is not valid. detail lists each problem.