openapi: 3.1.0
info:
  title: API Weblyrics
  version: 0.1.4
  summary: Pesquisa no dicionário de acordes (instrumentoX) e no Universo WL.
  description: >-
    A **API Weblyrics** expõe o dicionário de acordes — posições no braço para instrumentos de
    cordas dedilhadas (violão, guitarra, cavaquinho, viola caipira, etc.) — e o catálogo público do
    Universo.


    **instrumentoX:** combinação de um instrumento com uma afinação (ex.: violão 6 cordas; `tuning`
    array índice 0 = corda mais fina, ex. `E,B,G,D,A,E`). Campo na API: `instrument_x_id`.


    Busca por nome usa símbolos do catálogo (notação primária e alternativas de
    `chord_spec.notation`).


    Um único endpoint HTTP: `POST https://api.weblyrics.com.br/v1` com body JSON `{ call, data }`.


    **Autenticação:** header `x-api-key: wlk_…`. A chave **nunca** vai no body.


    Operações (`call`): instruments.list, instruments.get, chords.search, universe.songs.search,
    universe.artists.search. Cada variante do body está no oneOf de `ChordApiRequest`.


    Documentação humana: https://weblyrics.com.br/developers
  contact:
    name: Weblyrics
    url: https://weblyrics.com.br/developers
    email: contato@weblyrics.com.br
  license:
    name: Proprietary
servers:
  - url: https://api.weblyrics.com.br
    description: Produção
tags:
  - name: API Weblyrics
    description: Um único `POST /v1`; a operação é escolhida pelo campo `call` no body.
paths:
  /v1:
    post:
      operationId: weblyricsApiInvoke
      tags:
        - API Weblyrics
      summary: Invoca um call da API Weblyrics
      description: >-
        Escolha o **exemplo** (ou o seletor de `call` no portal) correspondente à operação desejada
        — o body muda por `call`.


        Envie `x-api-key: wlk_…` e body `{ "call": "…", "data": { … } }`.


        O request body é um **oneOf** por `call` (campos obrigatórios/opcionais em cada variante).


        Resposta 200: `{ call, data, meta? }`. Erros: `{ error, message?, contact? }` (código string
        em `error`).
      security:
        - ApiKeyHeader: []
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: "#/components/schemas/ChordApiRequest"
            examples:
              instrumentsList:
                summary: instruments.list
                description: Listar instrumentoX (paginado).
                value:
                  call: instruments.list
                  data:
                    limit: 50
              instrumentsGet:
                summary: instruments.get
                description: Obter um instrumentoX pelo UUID.
                value:
                  call: instruments.get
                  data:
                    instrument_x_id: 11111111-1111-4111-8111-111111111111
              chordsSearch:
                summary: chords.search — acorde Am
                description: Pesquisar no dicionário de acordes.
                value:
                  call: chords.search
                  data:
                    name: Am
                    format: json
                    limit: 20
              universeSongs:
                summary: universe.songs.search
                description: Pesquisar versões no Universo.
                value:
                  call: universe.songs.search
                  data:
                    q: boemia
                    format: json
              universeArtists:
                summary: universe.artists.search
                description: Pesquisar artistas no Universo.
                value:
                  call: universe.artists.search
                  data:
                    name_prefix: To
      responses:
        "200":
          description: Sucesso. O formato de `data` depende do `call` e de `data.format`.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ChordApiSuccess"
              examples:
                instrumentsList:
                  summary: instruments.list
                  value:
                    call: instruments.list
                    data:
                      items:
                        - instrument_x_id: 11111111-1111-4111-8111-111111111111
                          instrument_type: violão
                    meta:
                      limit: 50
                      offset: 0
                instrumentsGet:
                  summary: instruments.get
                  value:
                    call: instruments.get
                    data:
                      instrument_x_id: 11111111-1111-4111-8111-111111111111
                      instrument_type: violão
                      tuning:
                        - E
                        - B
                        - G
                        - D
                        - A
                        - E
                chordsSearch:
                  summary: chords.search (json)
                  value:
                    call: chords.search
                    data:
                      hits:
                        - symbol: Am
                          name: Am
                          query_name: Am
                          spelling: canonical
                          notation_source: primary
                          instrument_x_id: 11111111-1111-4111-8111-111111111111
                          string_count: 6
                          tuning:
                            - E
                            - B
                            - G
                            - D
                            - A
                            - E
                          tuning_name: Padrão
                    meta:
                      limit: 20
                      offset: 0
                universeSongs:
                  summary: universe.songs.search
                  value:
                    call: universe.songs.search
                    data:
                      items:
                        - title: Boemia
                          slug: boemia
                    meta:
                      limit: 20
                      offset: 0
                universeArtists:
                  summary: universe.artists.search
                  value:
                    call: universe.artists.search
                    data:
                      items:
                        - name: Toquinho
                    meta:
                      limit: 20
                      offset: 0
        "400":
          description: "`call`/`data` inválidos, JSON inválido, ou chave no body."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ChordApiError"
        "401":
          description: Chave ausente ou inválida.
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ChordApiError"
        "404":
          description: "Recurso não encontrado (ex.: instruments.get)."
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ChordApiError"
        "429":
          description: Rate limit (IP, chave ou cota diária).
          content:
            application/json:
              schema:
                $ref: "#/components/schemas/ChordApiError"
      x-wl-calls:
        - instruments.list
        - instruments.get
        - chords.search
        - universe.songs.search
        - universe.artists.search
components:
  securitySchemes:
    ApiKeyHeader:
      type: apiKey
      in: header
      name: x-api-key
      description: "Chave API Weblyrics (`wlk_…`). Única forma documentada para clientes: header
        `x-api-key`. Nunca enviar a chave no body."
  schemas:
    ApiCall:
      type: string
      enum:
        - instruments.list
        - instruments.get
        - chords.search
        - universe.songs.search
        - universe.artists.search
      description: Identificador versionado da operação (`call`).
    ResponseFormat:
      type: string
      enum:
        - json
        - txt
        - markdown
        - html
      default: json
      description: Formato da resposta. `json` (padrão) devolve objeto tipado; `txt` / `markdown` / `html`
        serializam o resultado.
    ChordInclude:
      type: string
      enum:
        - meta
        - diagram_svg
        - tablature
      description: Item de `include` em chords.search.
    InstrumentsListData:
      type: object
      title: instruments.list — data
      additionalProperties: false
      description: Todos os campos são opcionais. Sem filtros, lista instrumentoX do sistema com paginação.
      properties:
        instrument_type:
          type: string
          minLength: 1
          description: "Opcional. Filtra pelo tipo de instrumento (ex.: violão, guitarra). Cada item retornado
            é um instrumentoX."
        limit:
          type: integer
          minimum: 1
          maximum: 100
          default: 20
          description: Tamanho da página (opcional).
        offset:
          type: integer
          minimum: 0
          default: 0
          description: Deslocamento 0-based (opcional).
    InstrumentsGetData:
      type: object
      title: instruments.get — data
      additionalProperties: false
      required:
        - instrument_x_id
      description: "`instrument_x_id` é obrigatório."
      properties:
        instrument_x_id:
          type: string
          format: uuid
          description: Obrigatório. UUID do instrumentoX (instrumento + afinação).
    ChordsSearchData:
      type: object
      title: chords.search — data
      additionalProperties: false
      description: "Obrigatório: pelo menos um de `name`, `name_prefix`, `name_contains`, `frets` ou
        `instrument_x_id`. Consulta o dicionário de acordes (cordas dedilhadas). Os campos `name*`
        são texto digitado; o filtro aplica-se a `v_chord_catalog.symbol` (inclui `spelling`
        canonical/enharmonic e `notation_source` primary/alternative). Cada hit inclui `symbol`,
        `name`, `query_name`, `spelling`, `notation_source`, `tuning`, `tuning_name` e
        `string_count`; `include: meta` acrescenta `spec_group`/`spec_name`/`spec_formula`."
      properties:
        name:
          type: string
          minLength: 1
          description: "Opcional (critério). Símbolo exato a buscar em `symbol` (ex.: Am, C7, A#/C##). Aliases
            enarmônicos são tentados via @wl/chord-theory."
        name_prefix:
          type: string
          minLength: 1
          description: Opcional (critério). Prefixo de `v_chord_catalog.symbol`.
        name_contains:
          type: string
          minLength: 1
          description: Opcional (critério). Substring em `v_chord_catalog.symbol`.
        ignore_bass:
          type: boolean
          default: false
          description: "Opcional. Ignora baixo slash: filtra `symbol` igual à raiz ou `raiz/%` (inclui
            enarmônicos)."
        frets:
          type: array
          items:
            type: integer
            minimum: -1
            maximum: 24
          description: Opcional (critério). Trastes por corda; índice 0 = corda mais fina (aguda). -1 = muda.
            Mesmo eixo que `tuning` do instrumentoX e `barre.from_string`/`to_string`.
        fingers:
          type: array
          items:
            type: integer
            minimum: -1
            maximum: 4
          description: "Opcional. Dedos associados aos trastes (mesma ordem: 0 = mais fina)."
        instrument_x_id:
          type: string
          format: uuid
          description: Opcional (critério ou filtro). Restringe ao instrumentoX indicado.
        instrument_type:
          type: string
          minLength: 1
          description: Opcional. Filtra por tipo de instrumento.
        min_base_fret:
          type: integer
          minimum: 0
          maximum: 24
          description: Opcional. Traste base mínimo da posição.
        priority_only:
          type: boolean
          default: false
          description: Opcional. Só posições prioritárias do dicionário.
        include:
          type: array
          items:
            type: string
            enum:
              - meta
              - diagram_svg
              - tablature
          description: "Partes extras em `chords.search`: metadados, diagrama SVG e/ou tablatura ASCII."
        hand:
          type: string
          enum:
            - left
            - right
          description: Opcional. Orientação destro/canhoto do diagrama.
        finger_numbers:
          type: boolean
          description: Opcional. Numeração de dedos no SVG.
        format:
          type: string
          enum:
            - json
            - txt
            - markdown
            - html
          default: json
          description: Formato da resposta. `json` (padrão) devolve objeto tipado; `txt` / `markdown` / `html`
            serializam o resultado.
        limit:
          type: integer
          minimum: 1
          maximum: 100
          default: 20
          description: Tamanho da página (opcional).
        offset:
          type: integer
          minimum: 0
          default: 0
          description: Deslocamento 0-based (opcional).
    UniverseSongsSearchData:
      type: object
      title: universe.songs.search — data
      additionalProperties: false
      description: "Obrigatório: pelo menos um de `q`, `title`, `artist`, `document_id`, `slug`,
        `canonical_slug` ou `canonical_entity_id`. Pesquisa versões publicadas no Universo."
      properties:
        q:
          type: string
          minLength: 1
          description: Opcional (critério). Busca textual geral.
        title:
          type: string
          minLength: 1
          description: Opcional (critério). Título da composição/versão.
        artist:
          type: string
          minLength: 1
          description: Opcional (critério). Nome de artista.
        document_id:
          type: string
          format: uuid
          description: Opcional (critério). UUID da versão (documento).
        slug:
          type: string
          minLength: 1
          description: Opcional (critério). Slug canônico da composição.
        canonical_slug:
          type: string
          minLength: 1
          description: Opcional (critério). Alias de `slug`.
        canonical_entity_id:
          type: string
          format: uuid
          description: Opcional (critério). UUID da entidade canônica.
        instrument_x_id:
          type: string
          format: uuid
          description: Opcional. Filtra pelo instrumentoX da versão.
        key:
          type: string
          minLength: 1
          description: Opcional. Tonalidade.
        tonality:
          type: string
          minLength: 1
          description: Opcional. Alias de `key`.
        min_likes:
          type: integer
          minimum: 0
          description: Opcional. Mínimo de curtidas da versão.
        author_system_only:
          type: boolean
          description: Opcional. Só versões do curador sistema.
        published_after:
          type: string
          format: date-time
        published_before:
          type: string
          format: date-time
        format:
          type: string
          enum:
            - json
            - txt
            - markdown
            - html
          default: json
          description: Formato da resposta. `json` (padrão) devolve objeto tipado; `txt` / `markdown` / `html`
            serializam o resultado.
        limit:
          type: integer
          minimum: 1
          maximum: 100
          default: 20
          description: Tamanho da página (opcional).
        offset:
          type: integer
          minimum: 0
          default: 0
          description: Deslocamento 0-based (opcional).
    UniverseArtistsSearchData:
      type: object
      title: universe.artists.search — data
      additionalProperties: false
      description: "Obrigatório: pelo menos um de `q`, `name` ou `name_prefix`. Pesquisa artistas ligados
        a publicações no Universo."
      properties:
        q:
          type: string
          minLength: 1
          description: Opcional (critério). Busca textual.
        name:
          type: string
          minLength: 1
          description: Opcional (critério). Nome do artista.
        name_prefix:
          type: string
          minLength: 1
          description: Opcional (critério). Prefixo do nome.
        limit:
          type: integer
          minimum: 1
          maximum: 100
          default: 20
          description: Tamanho da página (opcional).
        offset:
          type: integer
          minimum: 0
          default: 0
          description: Deslocamento 0-based (opcional).
    ChordApiRequest:
      oneOf:
        - type: object
          title: instruments.list — listar instrumentoX
          additionalProperties: false
          required:
            - call
            - data
          description: Body para a operação `instruments.list`.
          properties:
            call:
              type: string
              const: instruments.list
              description: Deve ser exatamente `instruments.list`.
            data:
              $ref: "#/components/schemas/InstrumentsListData"
        - type: object
          title: instruments.get — obter instrumentoX
          additionalProperties: false
          required:
            - call
            - data
          description: Body para a operação `instruments.get`.
          properties:
            call:
              type: string
              const: instruments.get
              description: Deve ser exatamente `instruments.get`.
            data:
              $ref: "#/components/schemas/InstrumentsGetData"
        - type: object
          title: chords.search — pesquisar acordes
          additionalProperties: false
          required:
            - call
            - data
          description: Body para a operação `chords.search`.
          properties:
            call:
              type: string
              const: chords.search
              description: Deve ser exatamente `chords.search`.
            data:
              $ref: "#/components/schemas/ChordsSearchData"
        - type: object
          title: universe.songs.search — pesquisar Universo
          additionalProperties: false
          required:
            - call
            - data
          description: Body para a operação `universe.songs.search`.
          properties:
            call:
              type: string
              const: universe.songs.search
              description: Deve ser exatamente `universe.songs.search`.
            data:
              $ref: "#/components/schemas/UniverseSongsSearchData"
        - type: object
          title: universe.artists.search — pesquisar artistas
          additionalProperties: false
          required:
            - call
            - data
          description: Body para a operação `universe.artists.search`.
          properties:
            call:
              type: string
              const: universe.artists.search
              description: Deve ser exatamente `universe.artists.search`.
            data:
              $ref: "#/components/schemas/UniverseArtistsSearchData"
    ChordApiSuccess:
      type: object
      title: Resposta de sucesso
      required:
        - call
        - data
      additionalProperties: false
      description: Envelope comum. `data` depende do `call` e do `format` pedido (json estruturado ou
        payload serializado).
      properties:
        call:
          type: string
          enum:
            - instruments.list
            - instruments.get
            - chords.search
            - universe.songs.search
            - universe.artists.search
          description: Operação executada.
        data:
          description: "Resultado tipado por `call`. Em JSON típico: lista/`items`/`hits` + paginação no
            `meta`. Em txt/markdown/html o handler pode devolver campos como `content` /
            `content_type`."
          type: object
          additionalProperties: true
        meta:
          type: object
          additionalProperties: true
          description: Metadados opcionais (paginação, cotas restantes, etc.).
    ChordApiError:
      type: object
      title: Resposta de erro
      required:
        - error
      additionalProperties: true
      properties:
        error:
          type: string
          description: Código do erro.
          examples:
            - missing_or_invalid_api_key
            - invalid_api_key
            - unknown_call
            - invalid_json
            - rate_limited_ip
            - rate_limited_key
            - rate_limited_day
            - not_found
        message:
          type: string
          description: Mensagem legível (quando presente).
        contact:
          type: string
          description: Contato de suporte (quando presente).
          examples:
            - contato@weblyrics.com.br
        known_calls:
          type: array
          items:
            type: string
          description: Presente em `unknown_call`.
        details:
          type: object
          additionalProperties: true
          description: Detalhes opcionais de validação.
