> ## Documentation Index
> Fetch the complete documentation index at: https://docs.periphery.exposed/llms.txt
> Use this file to discover all available pages before exploring further.

# Search apps

> Runs a query in the console's syntax and returns one page of 50 hits.
Free text, bare domains, and `key:value` filters work exactly as in
the search bar; see the filter reference in the guides.

Searches are unlimited; only the per-second rate limit applies. An
empty `q` returns an empty page. `has:creds` always applies, since API
access and the filter are both Plus and Pro features.




## OpenAPI

````yaml /openapi.yaml get /v1/search
openapi: 3.1.0
info:
  title: Periphery API
  version: 1.0.0
  summary: Search Periphery's index of publicly reachable web apps as JSON.
  description: |
    The API returns the same search results and app records as the console.
    Every request needs an API key issued on the console's account page,
    sent as `Authorization: Bearer <key>` or `X-API-Key: <key>`. API access
    is part of the Plus and Pro plans. Searches are unlimited; requests are
    limited to one per second per account.
  contact:
    name: Periphery
    email: contact@gglabs.fr
    url: https://docs.periphery.exposed
servers:
  - url: https://api.periphery.exposed
    description: Production
security:
  - bearerAuth: []
  - apiKeyHeader: []
tags:
  - name: Search
    description: Run a query and page through the hits.
  - name: Apps
    description: Read one app's full record.
paths:
  /v1/search:
    get:
      tags:
        - Search
      summary: Search apps
      description: |
        Runs a query in the console's syntax and returns one page of 50 hits.
        Free text, bare domains, and `key:value` filters work exactly as in
        the search bar; see the filter reference in the guides.

        Searches are unlimited; only the per-second rate limit applies. An
        empty `q` returns an empty page. `has:creds` always applies, since API
        access and the filter are both Plus and Pro features.
      operationId: search
      parameters:
        - name: q
          in: query
          required: true
          description: The query, in the console's search syntax.
          schema:
            type: string
          example: acme.com provider:vercel status:200
        - name: p
          in: query
          required: false
          description: >-
            Page number, starting at 1. 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.
          schema:
            type: integer
            minimum: 1
            default: 1
          example: 1
      responses:
        '200':
          description: One page of results.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SearchResponse'
              example:
                total: 2
                page: 1
                hits:
                  - hostname: acme-dashboard.vercel.app
                    title: Acme dashboard
                    status: 200
                    provider: vercel
                    faviconHash: -247388890
                    emails:
                      - ops@acme.com
                    hasCreds: true
                  - hostname: acme-com-staging.vercel.app
                    title: Acme (staging)
                    status: 401
                    provider: vercel
                    hasCreds: false
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/Forbidden'
        '429':
          $ref: '#/components/responses/RateLimited'
        '502':
          $ref: '#/components/responses/BackendError'
components:
  schemas:
    SearchResponse:
      type: object
      required:
        - total
        - page
        - hits
      properties:
        total:
          type: integer
          description: Number of apps matching the query, across all pages.
        page:
          type: integer
          description: The page returned, starting at 1.
        hits:
          type: array
          items:
            $ref: '#/components/schemas/SearchHit'
          description: Up to 50 hits for this page.
    SearchHit:
      type: object
      required:
        - hostname
        - title
        - status
        - provider
        - hasCreds
      properties:
        hostname:
          type: string
          description: The app's hostname, its stable identifier.
        title:
          type: string
          description: Page title at the last snapshot. Empty when the page had none.
        status:
          type: integer
          description: HTTP status at the last snapshot. 0 when unknown.
        provider:
          type: string
          description: Provider slug, as listed on the providers page.
        faviconHash:
          type: integer
          format: int32
          description: Shodan-compatible favicon hash. Omitted when no favicon was fetched.
        emails:
          type: array
          items:
            type: string
          description: Email addresses found on the page. Omitted when none.
        hasCreds:
          type: boolean
          description: True when at least one credential finding was verified.
    Error:
      type: object
      required:
        - error
      properties:
        error:
          type: string
          description: Human-readable reason.
  responses:
    Unauthorized:
      description: Missing or unknown API key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          examples:
            missing:
              summary: No key header
              value:
                error: missing API key
            invalid:
              summary: Unknown or rotated key
              value:
                error: invalid API key
    Forbidden:
      description: The account is on the Free plan, which has no API access.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: API access requires the Plus or Pro plan
    RateLimited:
      description: More than one request per second from this key.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: 'rate limit: 1 request per second'
    BackendError:
      description: The search backend did not answer in time. Retry after a moment.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/Error'
          example:
            error: search backend error
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      description: '`Authorization: Bearer <key>`. Used when both headers are present.'
    apiKeyHeader:
      type: apiKey
      in: header
      name: X-API-Key
      description: The same key in an `X-API-Key` header.

````