# Search Look up objects in your Stripe data. Some top level API resources support retrieval with search API methods. You can use the search APIs to retrieve your Stripe objects in a flexible manner. Using search is a faster alternative to [paginating](https://docs.stripe.com/api/pagination.md) through all resources. To create a search query, review the [Search query language](https://docs.stripe.com/search.md#search-query-language) and reference the query fields of the resource: - [Query fields for Charges](https://docs.stripe.com/search.md#query-fields-for-charges) - [Query fields for Customers](https://docs.stripe.com/search.md#query-fields-for-customers) - [Query fields for Invoices](https://docs.stripe.com/search.md#query-fields-for-invoices) - [Query fields for PaymentIntents](https://docs.stripe.com/search.md#query-fields-for-paymentintents) - [Query fields for Prices](https://docs.stripe.com/search.md#query-fields-for-prices) - [Query fields for Products](https://docs.stripe.com/search.md#query-fields-for-products) - [Query fields for Subscriptions](https://docs.stripe.com/search.md#query-fields-for-subscriptions) ## Limitations ### Minimum API version The minimum supported API Version to use search is `2020-08-27`. Read our [API upgrades guide](https://docs.stripe.com/upgrades.md) to learn more about upgrades. To use search without upgrading your account API version, you can override the API version on a single request by setting the `Stripe-Version` request header: ```bash -H "Stripe-Version: 2026-02-25.clover" ``` Read our [SDKs](https://docs.stripe.com/sdks.md#versioning) guide on how to override an API version when using a library. ### Data freshness Don’t use search for read-after-write flows (for example, searching immediately after a charge is made) because the data won’t be immediately available to search. Under normal operating conditions, data is searchable in under 1 minute. Propagation of new or updated data could be delayed during an outage. For read-after-write flows that require immediate data availability, use the various list APIs, such as [List invoices](https://docs.stripe.com/api/invoices/list.md)). These APIs aren’t subject to the availability delays mentioned above. ### Data mismatches In some cases, the data you use to find search results might not match the results that you receive. This can happen because the Search API filters using a cached version of the PaymentIntent `status`, but returns data based on the latest version of the PaymentIntent. For example, if you query the [Search Payment Intents API](https://docs.stripe.com/api/payment_intents/search.md) for PaymentIntents with the status `requires_capture`, it might return some PaymentIntents with the status `succeeded`. This happens because the Search API finds cached PaymentIntents that have the older `requires_capture` status, but returns the current `succeeded` status in the results. ### Rate limits We apply a [rate limit](https://docs.stripe.com/rate-limits.md) of up to 20 read operations per second which applies for all search endpoints in live mode and test environments. Live mode and test environment limits are separate. Keeping the rate limit in mind, for workloads where you need to run analytics on one or more API resources, [Sigma](https://docs.stripe.com/stripe-data/how-sigma-works.md) is much more efficient. For workloads where you need to export a large portion of your API resource, our [Data Pipeline](https://docs.stripe.com/stripe-data/access-data-in-warehouse.md) product is more efficient. ### Regional availability Search isn’t available to businesses in India. ### Test clock objects omitted in list all results Stripe list APIs (such as [List invoices](https://docs.stripe.com/api/invoices/list.md)) omit results generated by test clocks for list all requests. To see results generated by test clocks in these cases, you must request results within a specific parent, such as `test_clock`, `customer`, or `subscription`. For example, `GET /v1/invoices` won’t return test clock generated invoices, but `GET /v1/invoices/{customer_id}` returns all invoices for that customer, including those that are test clock generated. Similarly, you can specify a test clock ID in this example to get all invoices related to that test clock, or you can specify a subscription ID to return all invoices billed for that subscription, including test clock generated invoices. ### Pagination In rare cases, paginating through a result set can reorder some records, causing them to be missing or duplicated on a page. If you encounter this issue, contact us using the form at [Stripe support](https://support.stripe.com). ## Examples Here are some examples of what you can do with the [Search charges API](https://docs.stripe.com/api/charges/search.md) and [Search PaymentIntents API](https://docs.stripe.com/api/payment_intents/search.md): ### Charges metadata search Look up charges matching a custom metadata value. ```curl curl -G https://api.stripe.com/v1/charges/search \ -u "<>:" \ --data-urlencode query="metadata['key']:'value'" ``` ### Charges last4 search Look up charges matching the last 4 digits of the card used for the payment. ```curl curl -G https://api.stripe.com/v1/charges/search \ -u "<>:" \ --data-urlencode query="payment_method_details.card.last4:4242" ``` ### Customers email search Look up customers matching an email. ```curl curl -G https://api.stripe.com/v1/customers/search \ -u "<>:" \ --data-urlencode query="email:'sally@rocketrides.io'" ``` ### Negation filter Look up PaymentIntents not in the USD currency. ```curl curl -G https://api.stripe.com/v1/payment_intents/search \ -u "<>:" \ --data-urlencode query="-currency:'usd'" ``` ### Numeric filter Filter invoice objects with a `total` greater than 1000. ```curl curl -G https://api.stripe.com/v1/invoices/search \ -u "<>:" \ -d query="total>1000" ``` ### Combining multiple filters Look up charges matching a combination of metadata and currency. ```curl curl -G https://api.stripe.com/v1/charges/search \ -u "<>:" \ --data-urlencode query="metadata['key']:'value' AND currency:'usd'" ``` ## Search query language ### Query structure and terminology A query `clause` consists of a `field` followed by an `operator` followed by a `value`: | | | | | clause | `email:"amy@rocketrides.io"` | | field | `email` | | operator | `:` | | value | `amy@rocketrides.io` | You can combine up to 10 query clauses in a search by either separating them with a space, or using the `AND` or `OR` keywords (case insensitive). You can’t combine `AND` and `OR` in the same query. Furthermore, there’s no option to use parentheses to give priority to certain logic operators. By default, the API combines clauses with `AND` logic. The example query `email:"amy@rocketrides.io" metadata["key"]:"value"` matches records where both the email address is amy@rocketrides.io, and the metadata in the record includes `key` with a value of `value`. ### Creating a query which doesn’t match a clause You can negate query clauses using a `-` character. For example, the following search returns records that don’t match the email `amy@rocketrides.io`. `-email:"amy@rocketrides.io"` ### Field types, substring matching, and numeric comparators Every search field supports exact matching with a `:`. Certain fields such as `email` and `name` support substring matching. Certain other fields such as `amount` support numeric comparators like `>` and `<`. Each field includes a type that defines the operations you can use in the field. For a full list of available fields, see [supported query fields for each resource](https://docs.stripe.com/search.md#supported-query-fields-for-each-resource). Using an unsupported operator, such as specifying greater than (`>`) on a string, returns an error. | type | operators | | ------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- | | token | exact match (case insensitive) | | string | exact match, substring (case insensitive) An exact match on a string type returns any record where that record contains all of the words from the query in the same order. For example the query `name:"one two three"` would match both a result with the name “one two three” and a result with the name “one two three four”. | | numeric | exact match, greater than and less than | ### Quotes You must use quotation marks around string values. Quotation marks are optional for numeric values. For example: - `currency:"usd"` means quotes are required. - `payment_method_details.card.last4:1234` means quotes are optional. You can escape quotes inside of quotes with a backslash (`\`). `description:"the story called \"The Sky and the Sea.\""` ### Metadata You can perform searches on [metadata](https://docs.stripe.com/api/metadata.md) that you’ve added to objects that support it. Use the following format to construct a clause for a metadata search: `metadata[""]:""`. The following clause demonstrates how to create a clause that queries for records with a donation ID of “asdf-jkl”: `metadata["donation-id"]:"asdf-jkl"`. You can query for the presence of a metadata key on an object. The following clause would match all records where `donation-id` is a metadata key. `-metadata["donation-id"]:null` ### Search Syntax The following table lists the syntax that you can use to construct a query. | Syntax | Usage | Description | Examples | | -------------- | ----------------------------------------------------------------------- | ----------------------------------------------------------------------------- | ----------------------------------------------------------------------------------------------------- | | `:` | `field:value` | Exact match operator (case insensitive) | `currency:"eur"` returns records where the currency is exactly “EUR” in a case-insensitive comparison | | `AND`, `and` | `field:value1 AND field:value2` | The query returns only records that match both clauses (case insensitive) | `status:"active" AND amount:500` | | `OR`, `or` | `field:value1 OR field:value2` | The query returns records that match either of the clauses (case insensitive) | `currency:"usd" OR currency:"eur"` | | `-` | `-field:value` | Returns records that don’t match the clause | `-currency:"jpy"` returns records that aren’t in JPY | | `NULL`, `null` | `field:null` | A special token used for field presence (case insensitive) | `url:null` returns records where a URL field is empty | | `\` | `" \"\""` | Escape quotes within quotes | `description:"the story called \"The Sky and the Sea.\""` | | `~` | `field~value` | Substring match operator (substrings must be a minimum of 3 characters) | `email~"amy"` returns matches for amy@rocketrides.io and xamy | | `>`, `<`, `=` | - `fieldvalue` - `field>=value` - `field<=value` | Greater than/less than operators | `amount>="10"` brings up objects where the amount is 10 or greater | ## Supported query fields for each resource ### Query fields for Charges | Field | usage | Type (token, string, numeric) | | --------------------------------------------- | ----------------------------------------------------------------- | ----------------------------- | | amount | `amount>1000` | numeric | | billing_details.address.postal_code | `billing_details.address.postal_code:12345` | token | | created | `created>1620310503` | numeric | | currency | `currency:"usd"` | token | | customer | `customer:"cus_123"` | token | | disputed | `disputed:"true"` | token | | metadata | `metadata["key"]:"value"` | token | | payment_method_details.{{SOURCE}}.last4 | `payment_method_details.card.last4:1234` | token | | payment_method_details.{{SOURCE}}.exp_month | `payment_method_details.card_present.exp_month:12` | token | | payment_method_details.{{SOURCE}}.exp_year | `payment_method_details.interac_present.exp_year:2022` | token | | payment_method_details.{{SOURCE}}.brand | `payment_method_details.card.brand:"visa"` | token | | payment_method_details.{{SOURCE}}.fingerprint | `payment_method_details.card.fingerprint:"fp"` | token | | payment_method_details.{{SOURCE}}.reader | `payment_method_details.wechat_pay.reader:"tmr_FDOt2wlRZEdpd7"` | token | | payment_method_details.{{SOURCE}}.location | `payment_method_details.wechat_pay.location:"tml_FBakXQG8bQk4Mm"` | token | | refunded | `refunded:"true"` | token | | status | `status:"succeeded"` | token | For `SOURCE`, use `card`, `card_present`, `interac_present`, or any of the [additional payment methods that Terminal supports](https://docs.stripe.com/terminal/payments/additional-payment-methods.md). Use `card` for online charges, `interac_present` for Terminal card present charges for the Interac network, and `card_present` for other Terminal card present charges. When querying for Terminal-related fields not specific to cards, such as `reader` and `location`, you can also use other payment methods such as `wechat_pay`. The `disputed` field accepts only the tokens “true” and “false”, indicating the presence of disputes. `refunded:"true"` filters for fully-refunded charges, `refunded:"false"` filters for charges that haven’t been refunded at all or have been partially refunded, and `refunded:null` filters for non-refunded charges. ### Query fields for Customers | Field | usage | Type (token, string, numeric) | | -------- | ------------------------- | ----------------------------- | | created | `created>1620310503` | numeric | | email | `email~"amyt"` | string | | metadata | `metadata["key"]:"value"` | token | | name | `name~"amy"` | string | | phone | `phone:"+19999999999"` | string | ### Query fields for Invoices | Field | usage | Type (token, string, numeric) | | ---------------------------- | -------------------------------------------------------------- | ----------------------------- | | created | `created>1620310503` | numeric | | currency | `currency:"usd"` | token | | customer | `customer:"cus_123"` | token | | last_finalization_error_code | `last_finalization_error_code:"customer_tax_location_invalid"` | token | | last_finalization_error_type | `last_finalization_error_type:"invalid_request_error"` | token | | metadata | `metadata["key"]:"value"` | token | | number | `number:"MYSHOP-123"` | string | | receipt_number | `receipt_number:"RECEIPT-123"` | string | | status | `status:"open"` | string | | subscription | `subscription:"SUBS-123"` | string | | total | `total>1000` | numeric | ### Query fields for PaymentIntents | Field | usage | Type (token, string, numeric) | | -------- | ------------------------- | ----------------------------- | | amount | `amount>1000` | numeric | | created | `created>1620310503` | numeric | | currency | `currency:"usd"` | token | | customer | `customer:"cus_123"` | token | | metadata | `metadata["key"]:"value"` | token | | status | `status:"succeeded"` | token | ### Query fields for Prices | Field | usage | Type (token, string, numeric) | | ---------- | ------------------------------- | ----------------------------- | | active | `active:"true"` | token | | currency | `currency:"usd"` | token | | lookup_key | `lookup_key:"standard_monthly"` | string | | metadata | `metadata["key"]:"value"` | token | | product | `product:"prod_123"` | string | | type | `type:"recurring"` | token | ### Query fields for Products | Field | usage | Type (token, string, numeric) | | ----------- | ------------------------- | ----------------------------- | | active | `active:"true"` | token | | description | `description~"t-shirts"` | string | | metadata | `metadata["key"]:"value"` | token | | name | `name~"amy"` | string | | shippable | `shippable:"true"` | token | | url | `url~"/dinosaur_swag"` | string | ### Query fields for Subscriptions | Field | usage | Type (token, string, numeric) | | ----------- | ------------------------- | ----------------------------- | | created | `created>1620310503` | numeric | | metadata | `metadata["key"]:"value"` | token | | status | `status:"active"` | token | | canceled_at | `canceled_at>1721521117` | numeric |