Skip to main content
Use the Search API behind a search box or a command menu over an account’s data: find the customer behind an email or a card, open a payment from its ID or invoice number, or jump to a member by name. To filter one resource and page through every match, use that resource’s list endpoint instead.

Endpoints

Every search names one account with account_id, and the credential, whether an API key, OAuth token or scoped token, needs company:basic:read on it. An account the credential can’t read returns a 404, as if it didn’t exist. Each row is then checked on its own account with the permission its record type needs, and rows the credential can’t read are left out without an error: a credential without payment:basic:read on an account sees none of that account’s payments. Search account records lists the permission and fields of each record type. A query containing @ also needs member:email:read on the row’s account, and a phone number match needs member:phone:read.

Subaccounts

A platform can search its subaccounts in the same call with include_subaccounts. Their records match by ID, email, card digits or phone number, and the subaccounts themselves match by name, ID, store link, owner email, team member email or customer email. A subaccount is also found by the ID of one of its plans or payouts. Invoice numbers and a bare last 4 only match inside the named account, because those numbers repeat across accounts. account rows are account_id itself and, with include_subaccounts, its subaccounts. Every other row belongs to one of those accounts.

How the query is read

Search trims query, which has to be 2 to 250 characters, and reads its shape before it runs. An identifier is looked up directly, and its matches come first. Every query of 3 or more characters is also ranked as text, and ranked rows follow the identifier matches. A query can have more than one shape: a 10-digit number is read as a phone number and as an invoice number, and each is searched. Ranked text search needs at least 3 characters. A shorter query only finds exact identifiers, such as a short invoice number. A bare number is read as a phone number when it has 10 to 15 digits, and as an invoice number when it has up to 18. A longer number is only ranked. Search never runs a full card number. A query of 13 to 19 digits that matches a card network’s prefix and length and passes the card number checksum is refused with a 400. Other long numbers fail that check, so search runs them as usual.

Ordering

data comes in served order: identifier matches first, newest first within each kind of match, then ranked results, best match first. Rely on the order of data for ranking, and on match_reason for why a row matched. Each record appears once. When one type’s search index is unavailable, the response is still a 200, without that type’s ranked rows. first caps the number of rows: 20 by default, up to 100. There is no cursor yet, so a response is a single page. Identifier matches read the database. Ranked matches read a search index that catches up shortly after a record changes. To filter one resource by a field such as a payment’s status, or to page through every match, use that resource’s list endpoint.

Match reasons

match_reason says what the record matched on, so you can label a row without working out the reason yourself. Every identifier match has one. A ranked row has one when the query is the record’s whole ID or its whole title, in any letter case; any other ranked row has a match_reason of null.

Attributes

string | null
required
Why the row matched, or null for a ranked row whose whole ID or whole title isn’t the query. id: its ID, or a related one such as its user’s, its dispute’s, or a plan or payout ID for an account. link: a whop.com store or product link. name: its whole title. email: the email of the user it belongs to. owner_email, team_member_email or customer_email: the email of a subaccount’s owner, a member of its team, or one of its customers. card: its card’s first 6 or 8 and last 4 digits, or the last 4 alone. phone: the phone number of the user it belongs to. payment_number: the number of the invoice a payment collects, so an invoice from GET /invoices comes back as its payment.Available options: id, owner_email, team_member_email, email, customer_email, card, phone, payment_number, link, name
account or member or membership or payment or affiliate or review or resolution_center_case or promo_code
required
The matched record. Get the full record from its own endpoint by id.
SearchResult