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

# Look up keywords

> Keyword metrics by text, 1 to 100 keywords per call (repeat `q`), in one language (`language`, default `en`; the values are in GET /v1/languages). Each text is canonicalized (trimmed, single spaces, lowercase, Unicode NFC), so variants of one keyword count once. Known keywords come back in `data` with their `id`; a keyword Alura has not seen yet is listed in `pending` while it is fetched, or in `unfetched` with a `code` and `retry_after` when no fetch could start (a fetch limit, or fetching is switched off). Keywords are never `not_found`. Charged per keyword in `data`. Swedish and Chinese (Traditional) share one Google language code in Alura's data, so their `volume.google_monthly` is null.

Cost: 1 API credit per item returned.



## OpenAPI

````yaml /openapi.json get /v1/research/keywords
openapi: 3.1.0
info:
  title: Alura API
  version: 1.0.0
  description: Etsy market research for scripts and AI assistants.
servers:
  - url: https://api.alura.io
security:
  - apiKey: []
paths:
  /v1/research/keywords:
    get:
      summary: Look up keywords
      description: >-
        Keyword metrics by text, 1 to 100 keywords per call (repeat `q`), in one
        language (`language`, default `en`; the values are in GET
        /v1/languages). Each text is canonicalized (trimmed, single spaces,
        lowercase, Unicode NFC), so variants of one keyword count once. Known
        keywords come back in `data` with their `id`; a keyword Alura has not
        seen yet is listed in `pending` while it is fetched, or in `unfetched`
        with a `code` and `retry_after` when no fetch could start (a fetch
        limit, or fetching is switched off). Keywords are never `not_found`.
        Charged per keyword in `data`. Swedish and Chinese (Traditional) share
        one Google language code in Alura's data, so their
        `volume.google_monthly` is null.


        Cost: 1 API credit per item returned.
      operationId: research.keywords.lookup
      parameters:
        - name: q
          in: query
          required: true
          description: >-
            Keyword text; repeat `q` for each keyword (1-100). Keywords may
            contain commas.
          schema:
            minItems: 1
            maxItems: 100
            type: array
            items:
              type: string
            description: >-
              Keyword text; repeat `q` for each keyword (1-100). Keywords may
              contain commas.
            example:
              - personalized mug
          style: form
          explode: true
        - name: language
          in: query
          required: false
          description: >-
            ISO code of the keyword language, from GET /v1/languages; default
            `en`.
          schema:
            default: en
            description: >-
              ISO code of the keyword language, from GET /v1/languages; default
              `en`.
            type: string
            enum:
              - ar
              - cs
              - da
              - de
              - en
              - es
              - fi
              - fr
              - hu
              - it
              - ja
              - ko
              - nl
              - 'no'
              - pl
              - pt
              - ru
              - sv
              - zh-CN
              - zh-TW
        - name: fields
          in: query
          required: false
          description: >-
            Comma-separated dotted paths to return; `id`, `object` and `as_of`
            always come back.
          schema:
            type: string
      responses:
        '200':
          description: OK
          headers:
            Request-Id:
              $ref: '#/components/headers/Request-Id'
            Alura-Credits-Cost:
              $ref: '#/components/headers/Alura-Credits-Cost'
            Alura-Credits-Remaining:
              $ref: '#/components/headers/Alura-Credits-Remaining'
          content:
            application/json:
              schema:
                type: object
                properties:
                  object:
                    type: string
                    const: list
                  data:
                    type: array
                    items:
                      type: object
                      properties:
                        object:
                          type: string
                          const: research.keyword
                        id:
                          type: string
                          description: >-
                            Alura's keyword ID, as a string; one per keyword and
                            language. Use it with the other keyword endpoints.
                        keyword:
                          type: string
                          description: >-
                            The keyword in canonical form: trimmed, single
                            spaces, lowercase, Unicode NFC.
                        language:
                          type: string
                          description: The ISO code of its language (GET /v1/languages).
                        volume:
                          type: object
                          properties:
                            etsy_monthly:
                              anyOf:
                                - type: integer
                                - type: 'null'
                              description: >-
                                Alura's estimate of monthly searches on Etsy
                                (12-month average); null when unknown.
                            google_monthly:
                              anyOf:
                                - type: integer
                                - type: 'null'
                              description: >-
                                Average monthly Google searches; null when
                                unknown, and for Swedish and Chinese
                                (Traditional) while their Google data cannot be
                                told apart.
                          required:
                            - etsy_monthly
                            - google_monthly
                          additionalProperties: false
                        competition:
                          type: object
                          properties:
                            level:
                              description: >-
                                `very_low`, `low`, `moderate`, `high` or
                                `very_high` (open-ended); null when unknown.
                              type:
                                - string
                                - 'null'
                            competing_listings:
                              anyOf:
                                - type: integer
                                - type: 'null'
                              description: >-
                                Etsy listings competing for the keyword; 0 is a
                                real zero.
                          required:
                            - level
                            - competing_listings
                          additionalProperties: false
                        trend:
                          type: object
                          properties:
                            change_3m:
                              description: >-
                                Etsy search volume, last 3 months against the 3
                                before (0.12 = +12%); null when unknown.
                              type:
                                - number
                                - 'null'
                            change_yoy:
                              description: >-
                                Etsy search volume against a year earlier (0.30
                                = +30%); null when unknown.
                              type:
                                - number
                                - 'null'
                          required:
                            - change_3m
                            - change_yoy
                          additionalProperties: false
                        market:
                          type: object
                          properties:
                            avg_price_usd:
                              description: >-
                                Average price of the USD-priced listings ranking
                                for the keyword; null when there are none.
                              type:
                                - number
                                - 'null'
                            est_avg_monthly_sales:
                              description: >-
                                Estimated average monthly sales of the listings
                                ranking for the keyword. Always null for now:
                                Alura has no sound source for it yet.


                                Estimate: see the methodology (version 2026-10)
                                at
                                https://docs.alura.io/methodology/keyword-market.
                              type:
                                - number
                                - 'null'
                          required:
                            - avg_price_usd
                            - est_avg_monthly_sales
                          additionalProperties: false
                        as_of:
                          type: string
                          description: When the keyword was last calculated.
                      required:
                        - object
                        - id
                        - keyword
                        - language
                        - volume
                        - competition
                        - trend
                        - market
                        - as_of
                      additionalProperties: false
                  pending:
                    type: array
                    items:
                      type: string
                    description: Never-seen IDs being fetched now; ask again later. Free.
                  unfetched:
                    type: array
                    items:
                      type: object
                      properties:
                        keyword:
                          type: string
                        code:
                          type: string
                          description: >-
                            Why it was not fetched: `fetch_limit_reached` (a
                            daily fetch cap or the per-minute fetch rate),
                            `fetch_unavailable` (fetching is off or the queue is
                            full), `service_unavailable` (Alura could not ask
                            for it). New codes may be added.
                        retry_after:
                          type: integer
                          minimum: 1
                          description: Seconds to wait before asking for it again.
                      required:
                        - keyword
                        - code
                        - retry_after
                      additionalProperties: false
                    description: >-
                      Never-seen IDs that were not fetched, with the reason and
                      when to retry. Free.
                  not_found:
                    type: array
                    items:
                      type: string
                    description: IDs that do not exist on Etsy or are not available. Free.
                required:
                  - object
                  - data
                  - pending
                  - unfetched
                  - not_found
                additionalProperties: false
              example:
                object: list
                data:
                  - object: research.keyword
                    id: '88123'
                    keyword: personalized mug
                    language: en
                    volume:
                      etsy_monthly: 12400
                      google_monthly: 40500
                    competition:
                      level: high
                      competing_listings: 182000
                    trend:
                      change_3m: 0.12
                      change_yoy: 0.3
                    market:
                      avg_price_usd: 24.1
                      est_avg_monthly_sales: null
                    as_of: '2026-10-12T04:00:00.000Z'
                pending: []
                unfetched: []
                not_found: []
        '400':
          $ref: '#/components/responses/Problem400'
        '401':
          $ref: '#/components/responses/Problem401'
        '402':
          $ref: '#/components/responses/Problem402'
        '403':
          $ref: '#/components/responses/Problem403'
        '404':
          $ref: '#/components/responses/Problem404'
        '405':
          $ref: '#/components/responses/Problem405'
        '429':
          $ref: '#/components/responses/Problem429'
        '500':
          $ref: '#/components/responses/Problem500'
        '503':
          $ref: '#/components/responses/Problem503'
      x-codeSamples:
        - lang: bash
          label: cURL
          source: >-
            curl "https://api.alura.io/v1/research/keywords?q=personalized+mug"
            \
              -H "Authorization: Bearer $ALURA_API_KEY"
        - lang: typescript
          label: TypeScript
          source: >-
            const res = await
            fetch('https://api.alura.io/v1/research/keywords?q=personalized+mug',
            {
              headers: {
                Authorization: `Bearer ${process.env.ALURA_API_KEY}`,
              },
            });

            console.log(await res.json());
        - lang: python
          label: Python
          source: |-
            import json
            import os
            import urllib.request

            request = urllib.request.Request(
                "https://api.alura.io/v1/research/keywords?q=personalized+mug",
                headers={
                    "Authorization": f"Bearer {os.environ['ALURA_API_KEY']}",
                },
            )
            with urllib.request.urlopen(request) as response:
                print(json.load(response))
components:
  headers:
    Request-Id:
      description: '`req_` + ULID; quote it when reporting a problem.'
      schema:
        type: string
    Alura-Credits-Cost:
      description: API credits this call cost.
      schema:
        type: integer
    Alura-Credits-Remaining:
      description: >-
        API credits left in the workspace's monthly allowance, counting calls
        still in flight. Absent when it cannot be read right now.
      schema:
        type: integer
  responses:
    Problem400:
      description: Error
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://docs.alura.io/errors/invalid_request
            title: Invalid request
            status: 400
            code: invalid_request
            detail: Invalid request
            suggestion: Fix the request as the detail says, then send it again.
            retryable: false
            request_id: req_01JQ5W3H8M2N4P6R8T0V2X4Z6B
    Problem401:
      description: Error
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://docs.alura.io/errors/unauthorized
            title: Unauthorized
            status: 401
            code: unauthorized
            detail: Unauthorized
            suggestion: 'Send a valid API key as `Authorization: Bearer alura_sk_...`.'
            retryable: false
            request_id: req_01JQ5W3H8M2N4P6R8T0V2X4Z6B
    Problem402:
      description: Error
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://docs.alura.io/errors/credits_exhausted
            title: API credits exhausted
            status: 402
            code: credits_exhausted
            detail: API credits exhausted
            suggestion: Upgrade the plan or wait for the monthly reset.
            retryable: false
            request_id: req_01JQ5W3H8M2N4P6R8T0V2X4Z6B
    Problem403:
      description: Error
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://docs.alura.io/errors/plan_required
            title: Plan required
            status: 403
            code: plan_required
            detail: Plan required
            suggestion: Upgrade the workspace plan to use this operation.
            retryable: false
            request_id: req_01JQ5W3H8M2N4P6R8T0V2X4Z6B
    Problem404:
      description: Error
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://docs.alura.io/errors/not_found
            title: Not found
            status: 404
            code: not_found
            detail: Not found
            suggestion: Check the ID, or search for it first.
            retryable: false
            request_id: req_01JQ5W3H8M2N4P6R8T0V2X4Z6B
    Problem405:
      description: Error
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://docs.alura.io/errors/method_not_allowed
            title: Method not allowed
            status: 405
            code: method_not_allowed
            detail: Method not allowed
            suggestion: Use one of the methods in the Allow header.
            retryable: false
            request_id: req_01JQ5W3H8M2N4P6R8T0V2X4Z6B
    Problem429:
      description: Error
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://docs.alura.io/errors/rate_limited
            title: Rate limited
            status: 429
            code: rate_limited
            detail: Rate limited
            suggestion: Wait for Retry-After, then retry.
            retryable: true
            request_id: req_01JQ5W3H8M2N4P6R8T0V2X4Z6B
    Problem500:
      description: Error
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://docs.alura.io/errors/internal_error
            title: Internal error
            status: 500
            code: internal_error
            detail: Internal error
            suggestion: Retry; if it keeps failing, report the request_id.
            retryable: true
            request_id: req_01JQ5W3H8M2N4P6R8T0V2X4Z6B
    Problem503:
      description: Error
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://docs.alura.io/errors/credits_unavailable
            title: API credits unavailable
            status: 503
            code: credits_unavailable
            detail: API credits unavailable
            suggestion: Retry shortly.
            retryable: true
            request_id: req_01JQ5W3H8M2N4P6R8T0V2X4Z6B
  schemas:
    Problem:
      type: object
      description: RFC 9457 problem details.
      properties:
        type:
          type: string
          format: uri
        title:
          type: string
        status:
          type: integer
        code:
          type: string
          description: A code from the error catalog; new codes may be added.
          x-extensible-enum:
            - invalid_request
            - unknown_parameter
            - invalid_cursor
            - cursor_window_exceeded
            - id_type_mismatch
            - invalid_keyword
            - unauthorized
            - credits_exhausted
            - plan_required
            - insufficient_scope
            - workspace_required
            - workspace_locked
            - browser_refused
            - role_required
            - impersonation_refused
            - recent_sign_in_required
            - not_found
            - not_found_on_etsy
            - shop_opted_out
            - method_not_allowed
            - conflict
            - key_limit_reached
            - idempotency_processing
            - unprocessable
            - rate_limited
            - throttled
            - daily_credit_cap_exceeded
            - credits_reserved
            - fetch_limit_reached
            - internal_error
            - upstream_unavailable
            - credits_unavailable
            - service_unavailable
            - fetch_unavailable
            - upstream_timeout
        detail:
          type: string
        suggestion:
          type: string
        retryable:
          type: boolean
        request_id:
          type: string
        upgrade_url:
          type: string
          format: uri
          description: 'credits_exhausted and plan_required: where to upgrade the plan.'
        credits_needed:
          type: integer
          description: 'API credit refusals: what the call needed.'
        credits_remaining:
          type: integer
          description: >-
            API credit refusals: what is left (of the month, or of the day for
            daily_credit_cap_exceeded).
        resets_at:
          type: string
          format: date-time
          description: >-
            credits_exhausted and daily_credit_cap_exceeded: when the limit
            resets.
      required:
        - type
        - title
        - status
        - code
        - detail
        - suggestion
        - retryable
        - request_id
  securitySchemes:
    apiKey:
      type: http
      scheme: bearer
      description: 'An API key: `Authorization: Bearer alura_sk_...`.'

````

This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.