openapi: 3.1.0
info:
  title: 'EbooksDepository Search API'
  description: 'Search the EbooksDepository catalog and find bookshop links for ebooks and audiobooks. Anonymous and read-only: no key, no registration (see /auth.md). Every operation is a GET and therefore idempotent — retrying is always safe. Errors other than search degradation are RFC 9457 application/problem+json documents with a stable `code`; every response carries standard RateLimit headers. Human/agent twin: /api.md. The contract is served as YAML at /api/openapi.yaml and JSON at /api/openapi.json, with the conventional /openapi.json alias retained.'
  version: 1.3.0
  license:
    name: Proprietary
    url: 'https://ebooksdepository.com/es/pages/terms'
  contact:
    name: EbooksDepository
    url: 'https://ebooksdepository.com'
servers:
  -
    url: 'https://ebooksdepository.com'
x-mcp-servers:
  -
    name: 'EbooksDepository catalog'
    url: 'https://ebooksdepository.com/api/mcp'
    transport: streamable-http
  -
    name: 'EbooksDepository documentation'
    url: 'https://ebooksdepository.com/api/mcp/docs'
    transport: streamable-http
security: {}
paths:
  /api/v1/search:
    get:
      operationId: searchBooks
      summary: 'Search for ebooks and audiobooks'
      description: 'Search by title, author, or ISBN. The response includes catalog metadata and bookshop links.'
      parameters:
        -
          name: q
          in: query
          required: true
          description: 'A title, author name, or ISBN.'
          schema:
            type: string
            minLength: 1
        -
          name: lang
          in: query
          required: false
          description: 'An optional ISO 639-1 book-language code.'
          schema:
            type: string
            pattern: '^[a-z]{2}$'
        -
          name: limit
          in: query
          required: false
          description: 'The maximum number of results.'
          schema:
            type: integer
            default: 10
            minimum: 1
            maximum: 50
      responses:
        200:
          description: 'Search results.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SearchResponse'
          headers:
            RateLimit:
              description: 'Current policy state, e.g. "public-api";r=59.'
              schema:
                type: string
            RateLimit-Policy:
              description: 'The quota policy, e.g. "public-api";q=60;w=60.'
              schema:
                type: string
            RateLimit-Limit:
              description: 'Requests allowed per window.'
              schema:
                type: integer
            RateLimit-Remaining:
              description: 'Requests left in the current window.'
              schema:
                type: integer
        503:
          description: 'The search service is not available.'
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/SearchUnavailableResponse'
        429:
          $ref: '#/components/responses/RateLimited'
        default:
          $ref: '#/components/responses/ServerError'
components:
  schemas:
    SearchResponse:
      type: object
      required:
        - results
        - total
      properties:
        results:
          type: array
          items:
            $ref: '#/components/schemas/Publication'
        total:
          type: integer
          minimum: 0
        query:
          type: string
    SearchUnavailableResponse:
      type: object
      required:
        - results
        - total
        - error
      properties:
        results:
          type: array
          maxItems: 0
        total:
          const: 0
        error:
          type: string
    Publication:
      type: object
      required:
        - title
        - slug
        - author
        - authors_detail
        - publisher
        - publisher_detail
        - genres
        - isbn
        - language
        - formats
        - cover_url
        - page_count
        - published_year
        - url
        - stores
      properties:
        title:
          type: string
        slug:
          type: string
        author:
          type: string
        authors_detail:
          type: array
          items:
            $ref: '#/components/schemas/NamedCatalogLink'
        publisher:
          type:
            - string
            - 'null'
        publisher_detail:
          oneOf:
            -
              $ref: '#/components/schemas/NamedCatalogLink'
            -
              type: 'null'
        genres:
          type: array
          items:
            $ref: '#/components/schemas/NamedCatalogLink'
        isbn:
          type:
            - string
            - 'null'
        language:
          type:
            - string
            - 'null'
        formats:
          type: array
          items:
            type: string
        cover_url:
          type:
            - string
            - 'null'
          format: uri
        page_count:
          type:
            - integer
            - 'null'
        published_year:
          type:
            - integer
            - 'null'
        url:
          type: string
          format: uri
        stores:
          type: array
          items:
            $ref: '#/components/schemas/Store'
    NamedCatalogLink:
      type: object
      required:
        - name
        - slug
      properties:
        name:
          type: string
        slug:
          type: string
    Store:
      type: object
      required:
        - name
        - country
        - url
        - is_free
      properties:
        name:
          type: string
        country:
          type:
            - string
            - 'null'
        url:
          type: string
          format: uri
        is_free:
          type: boolean
    Problem:
      type: object
      description: 'RFC 9457 problem document. Branch on `code`, not on prose; codes are documented at /api.md#errors.'
      required:
        - type
        - title
        - status
        - detail
        - code
      properties:
        type:
          type: string
          format: uri
        title:
          type: string
        status:
          type: integer
        detail:
          type: string
        code:
          type: string
          enum:
            - not_found
            - validation_failed
            - rate_limit_exceeded
            - server_error
            - unauthenticated
        errors:
          type: object
          description: 'Present on validation_failed: parameter name to messages.'
  responses:
    RateLimited:
      description: 'The client exceeded the public limit of 60 requests per minute. Wait Retry-After seconds.'
      headers:
        RateLimit:
          description: 'Current policy state, e.g. "public-api";r=59.'
          schema:
            type: string
        RateLimit-Policy:
          description: 'The quota policy, e.g. "public-api";q=60;w=60.'
          schema:
            type: string
        RateLimit-Limit:
          description: 'Requests allowed per window.'
          schema:
            type: integer
        RateLimit-Remaining:
          description: 'Requests left in the current window.'
          schema:
            type: integer
        Retry-After:
          description: 'Seconds to wait before retrying.'
          schema:
            type: integer
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
    ServerError:
      description: 'Any undocumented failure. Nothing about the failure leaks; retrying is safe (reads only).'
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
externalDocs:
  description: 'EbooksDepository developer portal and API quickstart'
  url: 'https://ebooksdepository.com/developers'

