Runs a query in the console’s syntax and returns one page of up to 50
hits. Free text, bare domains, and key:value filters work exactly
as in the search bar; see the filter reference in the guides.
q is required: a missing or blank q is answered
400 query_required. A q that parses to nothing (say, only a
filter whose value cannot be read, like status:2oo) returns an
empty page whose query is "", showing the filter was dropped.
Neither is counted.
Each request counts as one search against the account’s monthly
allowance, page by page, and the per-second rate limit applies.
Requests refused before the quota check (400, 401, 403, 405,
429) never count a search; a 502, 503 or 504 after it does. has:creds always applies, since API access and
the filter are both Plus features.
Hits are ordered by relevance when the query has free text, and
otherwise by firstSeen, newest first, then lastSeen, newest first.
Pages are offsets over live data, so an app can move between pages
while you page: deduplicate by hostname. Stop when hasMore is
false. Only GET is allowed; any other method, HEAD included, is
answered 405 before the key is checked and never runs a search.
The query, in the console's search syntax. Up to 256 characters (Unicode code points, not bytes) and 10 terms, where each free-text word and each filter value counts as one term. A missing or blank q is answered 400 query_required and is not counted.
Page number, from 1 to 20000. Each page holds 50 hits. A page past the end returns an empty hits array. Values below 1 or that are not numbers are treated as 1. A larger page, including numbers too large to read, is answered 400 page_out_of_range. Unlike the console, which stops at page 20, the API pages through the full result set, but every page costs one search from the monthly allowance.
The canonical form of the query Periphery ran. Filter values it could not read are dropped or searched as text, so this shows what actually ran. "" when q parsed to nothing (a missing or blank q is answered 400 query_required instead).
Number of apps matching the query, across all pages, from a count cached up to 10 minutes and raised to at least what this page proves. Counting stops at 1,000,000; see totalCapped.
{"docsConfig":{"theme":"mint","$schema":"https://mintlify.com/docs.json","name":"Periphery","colors":{"primary":"#0c0c0d","light":"#ffe14a","dark":"#0c0c0d"},"logo":{"light":"https://mintcdn.com/gg-labs-70a5437a/mTnMuteMHaJB6c5o/logo/light.svg?fit=max\u0026auto=format\u0026n=mTnMuteMHaJB6c5o\u0026q=85\u0026s=eeacb576280cb86ed05eca5a5969d14e","dark":"https://mintcdn.com/gg-labs-70a5437a/mTnMuteMHaJB6c5o/logo/dark.svg?fit=max\u0026auto=format\u0026n=mTnMuteMHaJB6c5o\u0026q=85\u0026s=4b4e160f6c5abcbf5162838c0dbc20d8","href":"https://periphery.exposed"},"favicon":"https://mintcdn.com/gg-labs-70a5437a/mTnMuteMHaJB6c5o/logo/favicon.svg?fit=max\u0026auto=format\u0026n=mTnMuteMHaJB6c5o\u0026q=85\u0026s=842fc26ed64a63e05262ffbb0a1232fb","api":{"openapi":"openapi.yaml","playground":{"display":"interactive","proxy":true},"examples":{"defaults":"all","languages":["bash","python","javascript"]}},"appearance":{"default":"system"},"navbar":{"links":[{"href":"https://console.periphery.exposed","label":"Console"}]},"footer":{"links":[{"header":"Periphery","items":[{"label":"Pricing","href":"https://periphery.exposed/"},{"label":"Terms of service","href":"https://console.periphery.exposed/terms"},{"label":"Privacy policy","href":"https://console.periphery.exposed/privacy"},{"label":"Contact","href":"mailto:contact@periphery.exposed"}]}]},"search":{"prompt":"Search the docs..."},"fonts":{"family":"Space Grotesk"},"contextual":{"options":["copy","claude","chatgpt"],"display":"header"},"styling":{"latex":false},"navigation":{"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"gg-labs-70a5437a","hasAudioNarration":false,"actualSubdomain":"gg-labs-70a5437a","customDomains":[],"gitSource":{"type":"github","owner":"ggranjus","repo":"periphery","deployBranch":"main","contentDirectory":"docs/site","isPrivate":true,"mountPath":"","label":"","_id":"6af4a760a8ee1879625b5547"},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6af4a7b9a8ee1879625b66dc","clientVersion":"0.0.4102","searchFilterCounts":[]},"assistantConfig":{"enableAskAiButton":false,"enableStarterQuestions":false,"enableContextualStarterQuestions":false,"enableAskAiSearchBar":true},"basePath":"","hasChatPermissions":true,"hasWebMcpPermissions":true,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-rbac-roles","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"rbac-expansion","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-metadata","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-serve","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"live-agents","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":true},"customCss":[],"page":{"pagePath":"api-reference/search/search-apps","slug":"/api-reference/search/search-apps","pageMetadata":{"title":"Search apps","description":"Runs a query in the console's syntax and returns one page of up to 50\nhits. Free text, bare domains, and `key:value` filters work exactly\nas in the search bar; see the filter reference in the guides.\n\n`q` is required: a missing or blank `q` is answered\n`400 query_required`. A `q` that parses to nothing (say, only a\nfilter whose value cannot be read, like `status:2oo`) returns an\nempty page whose `query` is `\"\"`, showing the filter was dropped.\nNeither is counted.\n\nEach request counts as one search against the account's monthly\nallowance, page by page, and the per-second rate limit applies.\nRequests refused before the quota check (`400`, `401`, `403`, `405`,\n`429`) never count a search; a `502`, `503` or `504` after it does. `has:creds` always applies, since API access and\nthe filter are both Plus features.\n\nHits are ordered by relevance when the query has free text, and\notherwise by `firstSeen`, newest first, then `lastSeen`, newest first.\nPages are offsets over live data, so an app can move between pages\nwhile you page: deduplicate by `hostname`. Stop when `hasMore` is\nfalse. Only `GET` is allowed; any other method, `HEAD` included, is\nanswered `405` before the key is checked and never runs a search.\n","deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/apps","href":"/api-reference/search/search-apps","autogeneratedByOpenApi":true},"description":{"compiledSource":"\"use strict\";\nconst {Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n code: \"code\",\n p: \"p\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsxs(_Fragment, {\n children: [_jsxs(_components.p, {\n children: [\"Runs a query in the console’s syntax and returns one page of up to 50\\nhits. Free text, bare domains, and \", _jsx(_components.code, {\n children: \"key:value\"\n }), \" filters work exactly\\nas in the search bar; see the filter reference in the guides.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.code, {\n children: \"q\"\n }), \" is required: a missing or blank \", _jsx(_components.code, {\n children: \"q\"\n }), \" is answered\\n\", _jsx(_components.code, {\n children: \"400 query_required\"\n }), \". A \", _jsx(_components.code, {\n children: \"q\"\n }), \" that parses to nothing (say, only a\\nfilter whose value cannot be read, like \", _jsx(_components.code, {\n children: \"status:2oo\"\n }), \") returns an\\nempty page whose \", _jsx(_components.code, {\n children: \"query\"\n }), \" is \", _jsx(_components.code, {\n children: \"\\\"\\\"\"\n }), \", showing the filter was dropped.\\nNeither is counted.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Each request counts as one search against the account’s monthly\\nallowance, page by page, and the per-second rate limit applies.\\nRequests refused before the quota check (\", _jsx(_components.code, {\n children: \"400\"\n }), \", \", _jsx(_components.code, {\n children: \"401\"\n }), \", \", _jsx(_components.code, {\n children: \"403\"\n }), \", \", _jsx(_components.code, {\n children: \"405\"\n }), \",\\n\", _jsx(_components.code, {\n children: \"429\"\n }), \") never count a search; a \", _jsx(_components.code, {\n children: \"502\"\n }), \", \", _jsx(_components.code, {\n children: \"503\"\n }), \" or \", _jsx(_components.code, {\n children: \"504\"\n }), \" after it does. \", _jsx(_components.code, {\n children: \"has:creds\"\n }), \" always applies, since API access and\\nthe filter are both Plus features.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Hits are ordered by relevance when the query has free text, and\\notherwise by \", _jsx(_components.code, {\n children: \"firstSeen\"\n }), \", newest first, then \", _jsx(_components.code, {\n children: \"lastSeen\"\n }), \", newest first.\\nPages are offsets over live data, so an app can move between pages\\nwhile you page: deduplicate by \", _jsx(_components.code, {\n children: \"hostname\"\n }), \". Stop when \", _jsx(_components.code, {\n children: \"hasMore\"\n }), \" is\\nfalse. Only \", _jsx(_components.code, {\n children: \"GET\"\n }), \" is allowed; any other method, \", _jsx(_components.code, {\n children: \"HEAD\"\n }), \" included, is\\nanswered \", _jsx(_components.code, {\n children: \"405\"\n }), \" before the key is checked and never runs a search.\"]\n })]\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){return _jsx(_Fragment,{})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Search apps","description":"Runs a query in the console's syntax and returns one page of up to 50\nhits. Free text, bare domains, and `key:value` filters work exactly\nas in the search bar; see the filter reference in the guides.\n\n`q` is required: a missing or blank `q` is answered\n`400 query_required`. A `q` that parses to nothing (say, only a\nfilter whose value cannot be read, like `status:2oo`) returns an\nempty page whose `query` is `\"\"`, showing the filter was dropped.\nNeither is counted.\n\nEach request counts as one search against the account's monthly\nallowance, page by page, and the per-second rate limit applies.\nRequests refused before the quota check (`400`, `401`, `403`, `405`,\n`429`) never count a search; a `502`, `503` or `504` after it does. `has:creds` always applies, since API access and\nthe filter are both Plus features.\n\nHits are ordered by relevance when the query has free text, and\notherwise by `firstSeen`, newest first, then `lastSeen`, newest first.\nPages are offsets over live data, so an app can move between pages\nwhile you page: deduplicate by `hostname`. Stop when `hasMore` is\nfalse. Only `GET` is allowed; any other method, `HEAD` included, is\nanswered `405` before the key is checked and never runs a search.\n","deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/apps","href":"/api-reference/search/search-apps","autogeneratedByOpenApi":true}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":[],"openApiReferenceData":{"operation":{"tags":["Search"],"operationId":"search","summary":"Search apps","description":"Runs a query in the console's syntax and returns one page of up to 50\nhits. Free text, bare domains, and `key:value` filters work exactly\nas in the search bar; see the filter reference in the guides.\n\n`q` is required: a missing or blank `q` is answered\n`400 query_required`. A `q` that parses to nothing (say, only a\nfilter whose value cannot be read, like `status:2oo`) returns an\nempty page whose `query` is `\"\"`, showing the filter was dropped.\nNeither is counted.\n\nEach request counts as one search against the account's monthly\nallowance, page by page, and the per-second rate limit applies.\nRequests refused before the quota check (`400`, `401`, `403`, `405`,\n`429`) never count a search; a `502`, `503` or `504` after it does. `has:creds` always applies, since API access and\nthe filter are both Plus features.\n\nHits are ordered by relevance when the query has free text, and\notherwise by `firstSeen`, newest first, then `lastSeen`, newest first.\nPages are offsets over live data, so an app can move between pages\nwhile you page: deduplicate by `hostname`. Stop when `hasMore` is\nfalse. Only `GET` is allowed; any other method, `HEAD` included, is\nanswered `405` before the key is checked and never runs a search.\n","parameters":["6cdc8741-e310-4c53-84f2-f827cdefa55a","e0a89358-fb08-4bd0-9707-7b8fced1fa9e"],"responses":{"200":"b80b7080-ebb3-4935-947f-d3598e59a877","400":"db11e89f-f8d3-4a89-9760-1d64f0671b2f","401":"52526c70-0d3e-43e6-99a9-ba103e160060","403":"a389be57-0501-4f52-a1fe-12fd03e012d6","405":"7c579333-c437-4d7b-bff7-39e2ada97ece","429":"9167c320-99a6-42ef-8c71-f3e4c1aa16e6","502":"d57ead1e-5f3b-41c3-a2f6-cfb0f7f809aa","503":"63f04fce-6f53-4843-aef2-47651bc1c2a4","504":"409d6b2d-43c5-426f-ad08-775901e3da23"},"method":"get","type":"path","servers":["19896e04-b872-4f24-b294-86e8a71aba29"],"security":["e8d97991-1ec2-4a91-9ed7-ce83d3e697ce","f482e937-04e6-408d-b036-62dfee25f0ac"],"path":"/v1/apps","baseUrlOptions":["https://api.periphery.exposed"],"title":"Search apps","codeSamples":[],"requestExampleLanguages":["bash","python","javascript"],"requiredOnlyExamples":false,"requestExampleType":"generated","responseExampleType":"generated"},"dependencies":{"parameters":{"6cdc8741-e310-4c53-84f2-f827cdefa55a":{"name":"q","in":"query","required":true,"description":"The query, in the console's search syntax. Up to 256 characters (Unicode code points, not bytes) and 10 terms, where each free-text word and each filter value counts as one term. A missing or blank `q` is answered `400 query_required` and is not counted.","schema":{"type":"string","minLength":1,"maxLength":256,"pattern":"\\S","isRequired":true,"description":"The query, in the console's search syntax. Up to 256 characters (Unicode code points, not bytes) and 10 terms, where each free-text word and each filter value counts as one term. A missing or blank `q` is answered `400 query_required` and is not counted.","uniqueKey":"","typeLabel":"string"},"example":"acme.com provider:vercel"},"e0a89358-fb08-4bd0-9707-7b8fced1fa9e":{"name":"page","in":"query","required":false,"description":"Page number, from 1 to 20000. Each page holds 50 hits. A page past the end returns an empty `hits` array. Values below 1 or that are not numbers are treated as 1. A larger `page`, including numbers too large to read, is answered `400 page_out_of_range`. Unlike the console, which stops at page 20, the API pages through the full result set, but every page costs one search from the monthly allowance.","schema":{"type":"integer","minimum":1,"maximum":20000,"default":1,"isRequired":false,"description":"Page number, from 1 to 20000. Each page holds 50 hits. A page past the end returns an empty `hits` array. Values below 1 or that are not numbers are treated as 1. A larger `page`, including numbers too large to read, is answered `400 page_out_of_range`. Unlike the console, which stops at page 20, the API pages through the full result set, but every page costs one search from the monthly allowance.","uniqueKey":"","typeLabel":"integer"},"example":1}},"responses":{"b80b7080-ebb3-4935-947f-d3598e59a877":{"description":"One page of results.","headers":{"Cache-Control":{"description":"Always `no-store`, on every response.","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","required":["query","page","pageSize","hasMore","total","totalCapped","hits"],"properties":{"query":{"type":"string","description":"The canonical form of the query Periphery ran. Filter values it could not read are dropped or searched as text, so this shows what actually ran. `\"\"` when `q` parsed to nothing (a missing or blank `q` is answered `400 query_required` instead).","isRequired":true,"uniqueKey":"query","typeLabel":"string"},"page":{"type":"integer","description":"The page returned, starting at 1.","isRequired":true,"uniqueKey":"page","typeLabel":"integer"},"pageSize":{"type":"integer","description":"Hits per page, 50.","isRequired":true,"uniqueKey":"pageSize","typeLabel":"integer"},"hasMore":{"type":"boolean","description":"True when the next page holds at least one hit. Exact; always false on page 20000. Stop paging when it is false.","isRequired":true,"uniqueKey":"hasMore","typeLabel":"boolean"},"total":{"type":"integer","description":"Number of apps matching the query, across all pages, from a count cached up to 10 minutes and raised to at least what this page proves. Counting stops at 1,000,000; see `totalCapped`.","isRequired":true,"uniqueKey":"total","typeLabel":"integer"},"totalCapped":{"type":"boolean","description":"True when counting stopped at 1,000,000, so at least `total` apps match.","isRequired":true,"uniqueKey":"totalCapped","typeLabel":"boolean"},"hits":{"type":"array","items":{"type":"object","description":"One app, as a search hit returns it, and the first part of every app record. Strings, numbers and booleans are always present; timestamps are omitted when the event never happened; lists are `[]` when Periphery looked and found nothing and omitted when it never looked; signed URLs and `faviconHash` are omitted when absent. No field is ever `null`.","required":["hostname","provider","status","title","lastSeen","scanned","hasVerifiedCreds"],"properties":{"hostname":{"type":"string","description":"The app's hostname, lower-case ASCII, its stable identifier.","example":"acme-dashboard.vercel.app","isRequired":true,"uniqueKey":"hits.items.[INDEX].hostname","typeLabel":"string"},"provider":{"type":"string","description":"Provider slug, the value the `provider:` filter takes, such as `vercel`, `netlify`, `railway` or `cloudflare_pages`. An open enum: new providers are added over time, see the providers page.","example":"vercel","isRequired":true,"uniqueKey":"hits.items.[INDEX].provider","typeLabel":"string"},"status":{"type":"integer","description":"HTTP status from the last render or fallback request that got an answer; 0 when none was recorded. A bot-wall page does not update it.","example":200,"isRequired":true,"uniqueKey":"hits.items.[INDEX].status","typeLabel":"integer"},"title":{"type":"string","description":"Page title at the last capture; `\"\"` when the page had none or was never rendered.","isRequired":true,"uniqueKey":"hits.items.[INDEX].title","typeLabel":"string"},"lastSeen":{"type":"string","format":"date-time","description":"Time of Periphery's last visit that did not prove the host dead, whether or not the host answered. Not the capture time. RFC 3339 in UTC; always present.","isRequired":true,"uniqueKey":"hits.items.[INDEX].lastSeen","typeLabel":"string\u003cdate-time>"},"scanned":{"type":"boolean","description":"True when Periphery captured the page and stored a snapshot (text, emails and credential scans). False for a host it only probed for liveness: then `emails`, `verifiedDetectors` and the snapshot URLs are absent.","isRequired":true,"uniqueKey":"hits.items.[INDEX].scanned","typeLabel":"boolean"},"hasVerifiedCreds":{"type":"boolean","description":"True when at least one credential finding was verified, so `verifiedDetectors` is non-empty.","isRequired":true,"uniqueKey":"hits.items.[INDEX].hasVerifiedCreds","typeLabel":"boolean"},"firstSeen":{"type":"string","format":"date-time","description":"Time of the first visit that got any answer from the host, RFC 3339 in UTC. It never changes once set. For apps indexed before October 2026, the time Periphery indexed them. Omitted when the host has never answered.","uniqueKey":"hits.items.[INDEX].firstSeen","typeLabel":"string\u003cdate-time>"},"faviconHash":{"type":"integer","format":"int32","description":"Shodan-compatible favicon hash (mmh3). Present whenever a favicon was stored, even when the hash is 0; omitted otherwise.","uniqueKey":"hits.items.[INDEX].faviconHash","typeLabel":"integer\u003cint32>"},"faviconUrl":{"type":"string","format":"uri","description":"Signed URL of the stored favicon, valid for one hour; `GET /v1/apps/{hostname}` returns a fresh one without using a search. An SVG favicon downloads as an attachment when opened directly. Omitted when no favicon was stored.","uniqueKey":"hits.items.[INDEX].faviconUrl","typeLabel":"string\u003curi>"},"screenshotUrl":{"type":"string","format":"uri","description":"Signed URL of the stored screenshot, valid for one hour; `GET /v1/apps/{hostname}` returns a fresh one without using a search. It shows the page as captured and can show a secret in full. Omitted when there is no screenshot.","uniqueKey":"hits.items.[INDEX].screenshotUrl","typeLabel":"string\u003curi>"},"emails":{"type":"array","items":{"type":"string","uniqueKey":"hits.items.[INDEX].emails.items.[INDEX]","typeLabel":"string"},"description":"Email addresses found on the page, lower-cased and deduplicated, up to 100. `[]` when the page was scanned and had none; omitted when it was never scanned.","uniqueKey":"hits.items.[INDEX].emails","typeLabel":"string[]"},"verifiedDetectors":{"type":"array","items":{"type":"string","uniqueKey":"hits.items.[INDEX].verifiedDetectors.items.[INDEX]","typeLabel":"string"},"description":"Names of the detectors with a verified finding, deduplicated case-insensitively and sorted. Each works as `creds:\u003cname>`. `[]` when the credential scan found nothing verified; omitted when no credential scan was stored.","uniqueKey":"hits.items.[INDEX].verifiedDetectors","typeLabel":"string[]"}},"uniqueKey":"hits.items.[INDEX]","typeLabel":"object"},"description":"Up to 50 hits for this page; `[]` when none.","isRequired":true,"uniqueKey":"hits","typeLabel":"object[]"}},"uniqueKey":"","typeLabel":"object"},"examples":{"page":{"title":"page","value":{"query":"provider:vercel domain:acme.com","page":1,"pageSize":50,"hasMore":false,"total":3,"totalCapped":false,"hits":[{"hostname":"acme-com-preview.vercel.app","provider":"vercel","status":0,"title":"","firstSeen":"2026-10-12T03:22:48Z","lastSeen":"2026-10-28T19:10:05Z","scanned":false,"hasVerifiedCreds":false},{"hostname":"acme-com-staging.vercel.app","provider":"vercel","status":401,"title":"Acme (staging)","firstSeen":"2026-09-17T22:05:19Z","lastSeen":"2026-10-29T08:41:02Z","scanned":true,"emails":[],"hasVerifiedCreds":false,"verifiedDetectors":[]},{"hostname":"acme-dashboard.vercel.app","provider":"vercel","status":200,"title":"Acme dashboard","firstSeen":"2026-08-02T10:15:40Z","lastSeen":"2026-10-30T14:03:11Z","scanned":true,"faviconHash":-247388890,"faviconUrl":"https://s3.gra.io.cloud.ovh.net/periphery/favicons/acme-dashboard.vercel.app.ico?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Credential=…\u0026X-Amz-Date=20261105T091500Z\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject\u0026X-Amz-Signature=…","screenshotUrl":"https://s3.gra.io.cloud.ovh.net/periphery/screenshots/acme-dashboard.vercel.app.png?X-Amz-Algorithm=AWS4-HMAC-SHA256\u0026X-Amz-Credential=…\u0026X-Amz-Date=20261105T091500Z\u0026X-Amz-Expires=3600\u0026X-Amz-SignedHeaders=host\u0026x-id=GetObject\u0026X-Amz-Signature=…","emails":["ops@acme.com"],"hasVerifiedCreds":true,"verifiedDetectors":["Stripe"]}]}},"dropped":{"title":"dropped","value":{"query":"","page":1,"pageSize":50,"hasMore":false,"total":0,"totalCapped":false,"hits":[]}}},"exampleType":"examples"}},"exampleType":"examples"},"db11e89f-f8d3-4a89-9760-1d64f0671b2f":{"description":"`q` is missing or blank, the query is over 256 characters or 10 terms, or `page` is past the last page. Not counted.","headers":{"Cache-Control":{"description":"Always `no-store`, on every response.","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","required":["error","code"],"properties":{"error":{"type":"string","description":"Human-readable reason. It may change; switch on `code`.","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"code":{"type":"string","description":"Stable machine-readable reason. New codes may be added: treat an unknown code by its HTTP status.","enum":["query_required","query_too_long","too_many_terms","page_out_of_range","api_key_missing","api_key_invalid","plan_required","https_required","app_not_found","not_found","method_not_allowed","ip_rate_limited","rate_limited","monthly_limit_reached","unavailable","busy","maintenance","timeout"],"isRequired":true,"uniqueKey":"code","typeLabel":"enum\u003cstring>"}},"uniqueKey":"","typeLabel":"object"},"examples":{"queryRequired":{"title":"queryRequired","value":{"error":"q is required: give a search query","code":"query_required"}},"queryTooLong":{"title":"queryTooLong","value":{"error":"query too long: up to 256 characters","code":"query_too_long"}},"tooManyTerms":{"title":"tooManyTerms","value":{"error":"query too long: up to 10 terms (this one has 12)","code":"too_many_terms"}},"pageOutOfRange":{"title":"pageOutOfRange","value":{"error":"page is past the last page (20000)","code":"page_out_of_range"}}},"exampleType":"examples"}},"exampleType":"examples"},"52526c70-0d3e-43e6-99a9-ba103e160060":{"description":"Missing, unknown or rotated API key. Not counted.","headers":{"Cache-Control":{"description":"Always `no-store`, on every response.","schema":{"type":"string","const":"no-store"}},"WWW-Authenticate":{"description":"The Bearer challenge: `Bearer realm=\"api.periphery.exposed\"`, plus `error=\"invalid_token\"` when the key is unknown or rotated.","schema":{"type":"string"}}},"content":{"application/json":{"schema":{"type":"object","required":["error","code"],"properties":{"error":{"type":"string","description":"Human-readable reason. It may change; switch on `code`.","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"code":{"type":"string","description":"Stable machine-readable reason. New codes may be added: treat an unknown code by its HTTP status.","enum":["query_required","query_too_long","too_many_terms","page_out_of_range","api_key_missing","api_key_invalid","plan_required","https_required","app_not_found","not_found","method_not_allowed","ip_rate_limited","rate_limited","monthly_limit_reached","unavailable","busy","maintenance","timeout"],"isRequired":true,"uniqueKey":"code","typeLabel":"enum\u003cstring>"}},"uniqueKey":"","typeLabel":"object"},"examples":{"missing":{"title":"missing","value":{"error":"missing API key","code":"api_key_missing"}},"invalid":{"title":"invalid","value":{"error":"invalid API key","code":"api_key_invalid"}}},"exampleType":"examples"}},"exampleType":"examples"},"a389be57-0501-4f52-a1fe-12fd03e012d6":{"description":"The account is on the Free plan, which has no API access; or the request came over plain HTTP, in which case the key travelled in clear text and should be rotated. A `has:creds` query also needs the Plus plan, which every account with API access has. Not counted.","headers":{"Cache-Control":{"description":"Always `no-store`, on every response.","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","required":["error","code"],"properties":{"error":{"type":"string","description":"Human-readable reason. It may change; switch on `code`.","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"code":{"type":"string","description":"Stable machine-readable reason. New codes may be added: treat an unknown code by its HTTP status.","enum":["query_required","query_too_long","too_many_terms","page_out_of_range","api_key_missing","api_key_invalid","plan_required","https_required","app_not_found","not_found","method_not_allowed","ip_rate_limited","rate_limited","monthly_limit_reached","unavailable","busy","maintenance","timeout"],"isRequired":true,"uniqueKey":"code","typeLabel":"enum\u003cstring>"}},"uniqueKey":"","typeLabel":"object"},"examples":{"planRequired":{"title":"planRequired","value":{"error":"API access requires the Plus plan","code":"plan_required"}},"credsPlanRequired":{"title":"credsPlanRequired","value":{"error":"the has:creds filter requires the Plus plan","code":"plan_required"}},"httpsRequired":{"title":"httpsRequired","value":{"error":"HTTPS required: use https://api.periphery.exposed. A key sent over plain HTTP travelled in clear text: rotate it.","code":"https_required"}}},"exampleType":"examples"}},"exampleType":"examples"},"7c579333-c437-4d7b-bff7-39e2ada97ece":{"description":"A method other than `GET`, `HEAD` included. Checked before the key; never counted.","headers":{"Cache-Control":{"description":"Always `no-store`, on every response.","schema":{"type":"string","const":"no-store"}},"Allow":{"description":"`GET`.","schema":{"type":"string","const":"GET"}}},"content":{"application/json":{"schema":{"type":"object","required":["error","code"],"properties":{"error":{"type":"string","description":"Human-readable reason. It may change; switch on `code`.","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"code":{"type":"string","description":"Stable machine-readable reason. New codes may be added: treat an unknown code by its HTTP status.","enum":["query_required","query_too_long","too_many_terms","page_out_of_range","api_key_missing","api_key_invalid","plan_required","https_required","app_not_found","not_found","method_not_allowed","ip_rate_limited","rate_limited","monthly_limit_reached","unavailable","busy","maintenance","timeout"],"isRequired":true,"uniqueKey":"code","typeLabel":"enum\u003cstring>"}},"uniqueKey":"","typeLabel":"object"},"example":{"error":"method not allowed","code":"method_not_allowed"},"examples":{"Example":{"title":"Example","value":{"error":"method not allowed","code":"method_not_allowed"}}},"exampleType":"examples"}},"exampleType":"examples"},"9167c320-99a6-42ef-8c71-f3e4c1aa16e6":{"description":"Too many requests from this address (`ip_rate_limited`) or this\naccount (`rate_limited`, one per second): retry after `Retry-After`.\nOr the account's monthly searches are used up\n(`monthly_limit_reached`): stop until the allowance resets on the\n1st, 00:00 UTC; no `Retry-After` is sent. Not counted.\n","headers":{"Cache-Control":{"description":"Always `no-store`, on every response.","schema":{"type":"string","const":"no-store"}},"Retry-After":{"description":"Seconds to wait before retrying: 1 after a rate limit, 2 when busy, 5 when unavailable, 3600 during maintenance. Not sent with the monthly limit (it resets on the 1st, UTC) or a timeout (a retry within a minute answers the same `504`).","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["error","code"],"properties":{"error":{"type":"string","description":"Human-readable reason. It may change; switch on `code`.","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"code":{"type":"string","description":"Stable machine-readable reason. New codes may be added: treat an unknown code by its HTTP status.","enum":["query_required","query_too_long","too_many_terms","page_out_of_range","api_key_missing","api_key_invalid","plan_required","https_required","app_not_found","not_found","method_not_allowed","ip_rate_limited","rate_limited","monthly_limit_reached","unavailable","busy","maintenance","timeout"],"isRequired":true,"uniqueKey":"code","typeLabel":"enum\u003cstring>"}},"uniqueKey":"","typeLabel":"object"},"examples":{"ipRate":{"title":"ipRate","value":{"error":"rate limit: too many requests from this address","code":"ip_rate_limited"}},"rate":{"title":"rate","value":{"error":"rate limit: 1 request per second","code":"rate_limited"}},"monthly":{"title":"monthly","value":{"error":"monthly search limit reached","code":"monthly_limit_reached"}}},"exampleType":"examples"}},"exampleType":"examples"},"d57ead1e-5f3b-41c3-a2f6-cfb0f7f809aa":{"description":"Periphery could not answer: a database or search backend failure, or the service is down. The result is unknown, not empty. Retry after `Retry-After`. A search answered this after the quota check counts.","headers":{"Cache-Control":{"description":"Always `no-store`, on every response.","schema":{"type":"string","const":"no-store"}},"Retry-After":{"description":"Seconds to wait before retrying: 1 after a rate limit, 2 when busy, 5 when unavailable, 3600 during maintenance. Not sent with the monthly limit (it resets on the 1st, UTC) or a timeout (a retry within a minute answers the same `504`).","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["error","code"],"properties":{"error":{"type":"string","description":"Human-readable reason. It may change; switch on `code`.","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"code":{"type":"string","description":"Stable machine-readable reason. New codes may be added: treat an unknown code by its HTTP status.","enum":["query_required","query_too_long","too_many_terms","page_out_of_range","api_key_missing","api_key_invalid","plan_required","https_required","app_not_found","not_found","method_not_allowed","ip_rate_limited","rate_limited","monthly_limit_reached","unavailable","busy","maintenance","timeout"],"isRequired":true,"uniqueKey":"code","typeLabel":"enum\u003cstring>"}},"uniqueKey":"","typeLabel":"object"},"example":{"error":"Periphery is temporarily unavailable, try again in a moment","code":"unavailable"},"examples":{"Example":{"title":"Example","value":{"error":"Periphery is temporarily unavailable, try again in a moment","code":"unavailable"}}},"exampleType":"examples"}},"exampleType":"examples"},"63f04fce-6f53-4843-aef2-47651bc1c2a4":{"description":"`busy`: too many searches are running across Periphery (counts as a search). `maintenance`: Periphery is down for maintenance. Retry after `Retry-After`.","headers":{"Cache-Control":{"description":"Always `no-store`, on every response.","schema":{"type":"string","const":"no-store"}},"Retry-After":{"description":"Seconds to wait before retrying: 1 after a rate limit, 2 when busy, 5 when unavailable, 3600 during maintenance. Not sent with the monthly limit (it resets on the 1st, UTC) or a timeout (a retry within a minute answers the same `504`).","schema":{"type":"integer"}}},"content":{"application/json":{"schema":{"type":"object","required":["error","code"],"properties":{"error":{"type":"string","description":"Human-readable reason. It may change; switch on `code`.","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"code":{"type":"string","description":"Stable machine-readable reason. New codes may be added: treat an unknown code by its HTTP status.","enum":["query_required","query_too_long","too_many_terms","page_out_of_range","api_key_missing","api_key_invalid","plan_required","https_required","app_not_found","not_found","method_not_allowed","ip_rate_limited","rate_limited","monthly_limit_reached","unavailable","busy","maintenance","timeout"],"isRequired":true,"uniqueKey":"code","typeLabel":"enum\u003cstring>"}},"uniqueKey":"","typeLabel":"object"},"examples":{"busy":{"title":"busy","value":{"error":"Periphery is busy, try again in a moment","code":"busy"}},"maintenance":{"title":"maintenance","value":{"error":"Periphery is temporarily unavailable for maintenance, try again later","code":"maintenance"}}},"exampleType":"examples"}},"exampleType":"examples"},"409d6b2d-43c5-426f-ad08-775901e3da23":{"description":"The search ran past its time limit. Narrow the query with more words or a filter rather than retrying it as is: a retry within a minute answers the same `504` and counts as a search. No `Retry-After`.","headers":{"Cache-Control":{"description":"Always `no-store`, on every response.","schema":{"type":"string","const":"no-store"}}},"content":{"application/json":{"schema":{"type":"object","required":["error","code"],"properties":{"error":{"type":"string","description":"Human-readable reason. It may change; switch on `code`.","isRequired":true,"uniqueKey":"error","typeLabel":"string"},"code":{"type":"string","description":"Stable machine-readable reason. New codes may be added: treat an unknown code by its HTTP status.","enum":["query_required","query_too_long","too_many_terms","page_out_of_range","api_key_missing","api_key_invalid","plan_required","https_required","app_not_found","not_found","method_not_allowed","ip_rate_limited","rate_limited","monthly_limit_reached","unavailable","busy","maintenance","timeout"],"isRequired":true,"uniqueKey":"code","typeLabel":"enum\u003cstring>"}},"uniqueKey":"","typeLabel":"object"},"example":{"error":"Search took too long, narrow it with more words or a filter","code":"timeout"},"examples":{"Example":{"title":"Example","value":{"error":"Search took too long, narrow it with more words or a filter","code":"timeout"}}},"exampleType":"examples"}},"exampleType":"examples"}},"security":{"e8d97991-1ec2-4a91-9ed7-ce83d3e697ce":{"bearerAuth":{"type":"http","scheme":"bearer","description":"`Authorization: Bearer \u003ckey>`. Used when both headers are present.","scopes":[],"schemeName":"bearerAuth"}},"f482e937-04e6-408d-b036-62dfee25f0ac":{"apiKeyHeader":{"type":"apiKey","in":"header","name":"X-API-Key","description":"The same key in an `X-API-Key` header.","scopes":[],"schemeName":"apiKeyHeader"}}},"servers":{"19896e04-b872-4f24-b294-86e8a71aba29":{"url":"https://api.periphery.exposed","description":"Production"}},"processedSecurityOptions":[{"schemes":[{"scheme":{"type":"http","scheme":"bearer","description":"`Authorization: Bearer \u003ckey>`. Used when both headers are present.","scopes":[],"schemeName":"bearerAuth"},"schema":{"title":"Bearer Auth","type":"string","isRequired":true,"description":"`Authorization: Bearer \u003ckey>`. Used when both headers are present.","format":"bearer","typeLabel":"string\u003cbearer>","deprecated":false},"schemeName":"bearerAuth","name":"Authorization"}],"title":"bearerAuth"},{"schemes":[{"scheme":{"type":"apiKey","in":"header","name":"X-API-Key","description":"The same key in an `X-API-Key` header.","scopes":[],"schemeName":"apiKeyHeader"},"schema":{"title":"X-API-Key","type":"string","description":"The same key in an `X-API-Key` header.","isRequired":true,"typeLabel":"string","deprecated":false},"schemeName":"apiKeyHeader","name":"X-API-Key"}],"title":"apiKeyHeader"}]},"originalFileLocation":"openapi.yaml"},"subdomain":"gg-labs-70a5437a","siteName":"Periphery","title":"Search apps - Periphery","navMaps":{"firstHrefInVersion":{},"firstHrefInLanguage":{}},"lastModified":"2026-11-11T17:37:12.222Z","originalFileLocation":"api-reference/search/search-apps.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"Runs a query in the console\u0026#x27;s syntax and returns one page of up to 50 hits. Free text, bare domains, and key:value filters work exactly as in the search bar; see the filter reference in the guides. q is required: a missing or blank q is answered 400 query_required. A q that parses to nothing (say, only a filter whose value cannot be read, like status:2oo) returns an empty page whose query is \u0026quot;\u0026quot;, showing the filter was dropped. Neither is counted. Each request counts as one search against the account\u0026#x27;s monthly allowance, page by page, and the per-second rate limit applies. Requests refused before the quota check (400, 401, 403, 405, 429) never count a search; a 502, 503 or 504 after it does. has:creds always applies, since API access and the filter are both Plus features. Hits are ordered by relevance when the query has free text, and otherwise by firstSeen, newest first, then lastSeen, newest first. Pages are offsets over live data, so an app can move between pages while you page: deduplicate by hostname. Stop when hasMore is false. Only GET is allowed; any other method, HEAD included, is answered 405 before the key is checked and never runs a search.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Periphery\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/gg-labs-70a5437a/XCCtb_vtsBhKWxAb/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/gg-labs-70a5437a/XCCtb_vtsBhKWxAb/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/gg-labs-70a5437a/XCCtb_vtsBhKWxAb/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/gg-labs-70a5437a/XCCtb_vtsBhKWxAb/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/gg-labs-70a5437a/XCCtb_vtsBhKWxAb/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/gg-labs-70a5437a/XCCtb_vtsBhKWxAb/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/gg-labs-70a5437a/XCCtb_vtsBhKWxAb/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/gg-labs-70a5437a/XCCtb_vtsBhKWxAb/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/gg-labs-70a5437a/XCCtb_vtsBhKWxAb/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Search apps - Periphery\">\u003cmeta data-mint-head property=\"og:description\" content=\"Runs a query in the console\u0026#x27;s syntax and returns one page of up to 50 hits. Free text, bare domains, and key:value filters work exactly as in the search bar; see the filter reference in the guides. q is required: a missing or blank q is answered 400 query_required. A q that parses to nothing (say, only a filter whose value cannot be read, like status:2oo) returns an empty page whose query is \u0026quot;\u0026quot;, showing the filter was dropped. Neither is counted. Each request counts as one search against the account\u0026#x27;s monthly allowance, page by page, and the per-second rate limit applies. Requests refused before the quota check (400, 401, 403, 405, 429) never count a search; a 502, 503 or 504 after it does. has:creds always applies, since API access and the filter are both Plus features. Hits are ordered by relevance when the query has free text, and otherwise by firstSeen, newest first, then lastSeen, newest first. Pages are offsets over live data, so an app can move between pages while you page: deduplicate by hostname. Stop when hasMore is false. Only GET is allowed; any other method, HEAD included, is answered 405 before the key is checked and never runs a search.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Periphery\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://gg-labs-70a5437a.mintlify.app/api-reference/search/search-apps\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://gg-labs-70a5437a.mintlify.site/_mintlify/api/og/v2?division=Endpoints\u0026amp;title=Search+apps\u0026amp;description=Runs+a+query+in+the+console%27s+syntax+and+returns+one+page+of+up+to+50%0Ahits.+Free+text%2C+bare+domains%2C+and+%60key%3Avalue%60+filters+work+exactly%0Aas+in+the+search+bar%3B+\u0026amp;theme=4f81fb74dd819cb097465c8e\u0026amp;signature=a6b4815bc9cb5c8b10dc75cc45788cd89fb55b8d7aa372789b8fd209696c40f5\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Search apps - Periphery\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"Runs a query in the console\u0026#x27;s syntax and returns one page of up to 50 hits. Free text, bare domains, and key:value filters work exactly as in the search bar; see the filter reference in the guides. q is required: a missing or blank q is answered 400 query_required. A q that parses to nothing (say, only a filter whose value cannot be read, like status:2oo) returns an empty page whose query is \u0026quot;\u0026quot;, showing the filter was dropped. Neither is counted. Each request counts as one search against the account\u0026#x27;s monthly allowance, page by page, and the per-second rate limit applies. Requests refused before the quota check (400, 401, 403, 405, 429) never count a search; a 502, 503 or 504 after it does. has:creds always applies, since API access and the filter are both Plus features. Hits are ordered by relevance when the query has free text, and otherwise by firstSeen, newest first, then lastSeen, newest first. Pages are offsets over live data, so an app can move between pages while you page: deduplicate by hostname. Stop when hasMore is false. Only GET is allowed; any other method, HEAD included, is answered 405 before the key is checked and never runs a search.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://gg-labs-70a5437a.mintlify.site/_mintlify/api/og/v2?division=Endpoints\u0026amp;title=Search+apps\u0026amp;description=Runs+a+query+in+the+console%27s+syntax+and+returns+one+page+of+up+to+50%0Ahits.+Free+text%2C+bare+domains%2C+and+%60key%3Avalue%60+filters+work+exactly%0Aas+in+the+search+bar%3B+\u0026amp;theme=4f81fb74dd819cb097465c8e\u0026amp;signature=a6b4815bc9cb5c8b10dc75cc45788cd89fb55b8d7aa372789b8fd209696c40f5\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/gg-labs-70a5437a/XCCtb_vtsBhKWxAb/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Periphery\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#0c0c0d\">\u003clink data-mint-head rel=\"canonical\" href=\"https://gg-labs-70a5437a.mintlify.app/api-reference/search/search-apps\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/api-reference/search/search-apps.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://gg-labs-70a5437a.mintlify.app/#organization\",\"name\":\"Periphery\",\"url\":\"https://gg-labs-70a5437a.mintlify.app\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/gg-labs-70a5437a/mTnMuteMHaJB6c5o/logo/light.svg?fit=max\u0026auto=format\u0026n=mTnMuteMHaJB6c5o\u0026q=85\u0026s=eeacb576280cb86ed05eca5a5969d14e\"}},{\"@type\":\"WebSite\",\"@id\":\"https://gg-labs-70a5437a.mintlify.app#website\",\"name\":\"Periphery\",\"url\":\"https://gg-labs-70a5437a.mintlify.app\",\"publisher\":{\"@id\":\"https://gg-labs-70a5437a.mintlify.app/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://gg-labs-70a5437a.mintlify.app/api-reference/search/search-apps#webpage\",\"url\":\"https://gg-labs-70a5437a.mintlify.app/api-reference/search/search-apps\",\"name\":\"Search apps\",\"description\":\"Runs a query in the console's syntax and returns one page of up to 50 hits. Free text, bare domains, and key:value filters work exactly as in the search bar; see the filter reference in the guides. q is required: a missing or blank q is answered 400 query_required. A q that parses to nothing (say, only a filter whose value cannot be read, like status:2oo) returns an empty page whose query is \\\"\\\", showing the filter was dropped. Neither is counted. Each request counts as one search against the account's monthly allowance, page by page, and the per-second rate limit applies. Requests refused before the quota check (400, 401, 403, 405, 429) never count a search; a 502, 503 or 504 after it does. has:creds always applies, since API access and the filter are both Plus features. Hits are ordered by relevance when the query has free text, and otherwise by firstSeen, newest first, then lastSeen, newest first. Pages are offsets over live data, so an app can move between pages while you page: deduplicate by hostname. Stop when hasMore is false. Only GET is allowed; any other method, HEAD included, is answered 405 before the key is checked and never runs a search.\",\"dateModified\":\"2026-11-11T17:37:12.222Z\",\"isPartOf\":{\"@id\":\"https://gg-labs-70a5437a.mintlify.app#website\"},\"breadcrumb\":{\"@id\":\"https://gg-labs-70a5437a.mintlify.app/api-reference/search/search-apps#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://gg-labs-70a5437a.mintlify.app/api-reference/search/search-apps#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Periphery\",\"item\":\"https://gg-labs-70a5437a.mintlify.app\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Search apps\",\"item\":\"https://gg-labs-70a5437a.mintlify.app/api-reference/search/search-apps\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://gg-labs-70a5437a.mintlify.app/api-reference/search/search-apps#apireference\",\"headline\":\"Search apps\",\"name\":\"Search apps\",\"description\":\"Runs a query in the console's syntax and returns one page of up to 50 hits. Free text, bare domains, and key:value filters work exactly as in the search bar; see the filter reference in the guides. q is required: a missing or blank q is answered 400 query_required. A q that parses to nothing (say, only a filter whose value cannot be read, like status:2oo) returns an empty page whose query is \\\"\\\", showing the filter was dropped. Neither is counted. Each request counts as one search against the account's monthly allowance, page by page, and the per-second rate limit applies. Requests refused before the quota check (400, 401, 403, 405, 429) never count a search; a 502, 503 or 504 after it does. has:creds always applies, since API access and the filter are both Plus features. Hits are ordered by relevance when the query has free text, and otherwise by firstSeen, newest first, then lastSeen, newest first. Pages are offsets over live data, so an app can move between pages while you page: deduplicate by hostname. Stop when hasMore is false. Only GET is allowed; any other method, HEAD included, is answered 405 before the key is checked and never runs a search.\",\"url\":\"https://gg-labs-70a5437a.mintlify.app/api-reference/search/search-apps\",\"mainEntityOfPage\":{\"@id\":\"https://gg-labs-70a5437a.mintlify.app/api-reference/search/search-apps#webpage\"},\"dateModified\":\"2026-11-11T17:37:12.222Z\",\"publisher\":{\"@id\":\"https://gg-labs-70a5437a.mintlify.app/#organization\"},\"isPartOf\":{\"@id\":\"https://gg-labs-70a5437a.mintlify.app#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Periphery\",\"publisher\":{\"@type\":\"Organization\",\"name\":\"Periphery\"},\"provider\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","agentPointerHref":"/api-reference/search/search-apps.md","siteName":"Periphery","nav":{"global":null,"tabs":[{"tab":"Guides","icon":"book-open","pages":[{"title":"Guides","href":""}]},{"tab":"API reference","icon":"square-terminal","groups":[{"group":"Using the API","pages":[{"title":"API overview","href":"/api/overview"},{"title":"API recipes","href":"/api/recipes"},{"title":"Authentication","href":"/api/authentication"},{"title":"Limits and errors","href":"/api/limits-and-errors"},{"title":"API changelog","description":"Every change to the Periphery API contract, newest first.","href":"/api/changelog"}]},{"group":"Endpoints","pages":[{"title":"Search apps","deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/apps","href":"/api-reference/search/search-apps"},{"title":"Get an app","description":"Returns the full record for one hostname: its summary (the same\nfields and values a search hit carries), the visible page `text`\nand, on Plus, the masked `credentials`. The record is read live, so\nit can be newer than a cached search page; when they differ, the\nrecord wins.\n\nIt does not use a search from the monthly allowance, but shares the\none request per second budget. Use it to refresh an app's signed\nURLs, which expire after one hour.\n\nOnly hosts a search can return have a record: a host Periphery has\nnever visited, or one it proved dead, answers `404 app_not_found`.\n`HEAD` is allowed and answers like `GET` without a body; any other\nmethod is answered `405` before the key is checked.\n","deprecated":null,"version":null,"openapi":"/openapi.yaml get /v1/apps/{hostname}","href":"/api-reference/apps/get-an-app"}]}]},{"tab":"MCP server","icon":"plug","pages":[{"title":"MCP server","href":"/mcp/overview"}]}]},"basePath":"","title":"Search apps - Periphery","buildId":"dpl_596ePT575z4qnAFksq1biRW97aLY","deploymentId":"dpl_596ePT575z4qnAFksq1biRW97aLY","dynamics":["c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["OpenApiReferenceProvider-C9Wu0MeN.js","utils-jWgu-6Qf.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-DBD8f9qn.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-BGuX1ui5.js","snippetPresets-Evy63nQB.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","conditional-requirements-CFM0id0Q.js","ApiExamples-BQHO1lnV.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-B6C8m-t_.js","shallow-BG4cT0fH.js","getApiPlaygroundDisplay-CgEPrE-D.js","CodeSnippet-CU8JyZ9N.js","CodeSnippets-BnxHU32T.js","Page-D6S0Yh6q.js","getPastedJson-CwiYOonh.js","icon-DYDpWmDf.js","MethodPill-C-J-l7_c.js","DuplicateIcon-B6ARwg9w.js","createIcon-Dsv4MtDq.js","DynamicMarkdown-CtasenyM.js","SectionHeading-YNcgYwjB.js","axios-vUo_bRtp.js","Markdown-CwLx6PAg.js","clsx-C3kuh_dz.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-CmKHfscc.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink-U3mI6Ljh.js"]}