> ## 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.

# List changes

> The changes Alura made to the listings of your connected Etsy shops, newest first: which fields changed, from what to what, who made the change and where it came from. Filter by `shop_id`, `listing_id`, `source` and `from`/`to` (when it was made; `to` is exclusive). In this version every change is one made in Alura (by someone in the app, an automation, or an AI optimization or creation applied there): history only, never revertable (`not_revertable_reason: legacy_app_write`). Not every Alura write is in it: Alura's A/B tests (their listing, inventory, photo and video changes) and the legacy app at app.alura.io (its edits, photos, videos, auto-renew and publishing) write to Etsy around the change log, so their changes can be missing. Edits made directly on Etsy, and by tools outside Alura, are not in it either. A change is shown under the shop its listing belongs to. A shop or listing outside the workspace is 404. `total` is exact up to 1,000 changes, then `{"value": 1000, "relation": "gte"}` (below the usual 10,000: each change's shop is checked one row at a time). Costs 1 API credit per page with results; an empty page is free.

Cost: 1 API credit per page.



## OpenAPI

````yaml /openapi.json get /v1/workspace/changes
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/workspace/changes:
    get:
      summary: List changes
      description: >-
        The changes Alura made to the listings of your connected Etsy shops,
        newest first: which fields changed, from what to what, who made the
        change and where it came from. Filter by `shop_id`, `listing_id`,
        `source` and `from`/`to` (when it was made; `to` is exclusive). In this
        version every change is one made in Alura (by someone in the app, an
        automation, or an AI optimization or creation applied there): history
        only, never revertable (`not_revertable_reason: legacy_app_write`). Not
        every Alura write is in it: Alura's A/B tests (their listing, inventory,
        photo and video changes) and the legacy app at app.alura.io (its edits,
        photos, videos, auto-renew and publishing) write to Etsy around the
        change log, so their changes can be missing. Edits made directly on
        Etsy, and by tools outside Alura, are not in it either. A change is
        shown under the shop its listing belongs to. A shop or listing outside
        the workspace is 404. `total` is exact up to 1,000 changes, then
        `{"value": 1000, "relation": "gte"}` (below the usual 10,000: each
        change's shop is checked one row at a time). Costs 1 API credit per page
        with results; an empty page is free.


        Cost: 1 API credit per page.
      operationId: workspace.changes.list
      parameters:
        - name: shop_id
          in: query
          required: false
          description: >-
            Only these connected shops, comma-separated; default every connected
            shop of the workspace. A shop outside the workspace is 404.
          schema:
            description: >-
              Only these connected shops, comma-separated; default every
              connected shop of the workspace. A shop outside the workspace is
              404.
            type: array
            items:
              type: string
          style: form
          explode: true
        - name: listing_id
          in: query
          required: false
          description: >-
            Only changes to this listing. A listing outside the workspace is
            404.
          schema:
            description: >-
              Only changes to this listing. A listing outside the workspace is
              404.
            type: string
            pattern: ^[0-9]{1,20}$
        - name: source
          in: query
          required: false
          description: >-
            Only changes from this source: app, api, automation, ai_optimize,
            ai_create, revert.
          schema:
            description: >-
              Only changes from this source: app, api, automation, ai_optimize,
              ai_create, revert.
            type: string
            enum:
              - app
              - api
              - automation
              - ai_optimize
              - ai_create
              - revert
            example: ai_optimize
        - name: from
          in: query
          required: false
          description: >-
            Only changes made at or after this time: a date (YYYY-MM-DD,
            midnight UTC) or an ISO 8601 date-time.
          schema:
            description: >-
              Only changes made at or after this time: a date (YYYY-MM-DD,
              midnight UTC) or an ISO 8601 date-time.
            type: string
            pattern: >-
              ^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}(:\d{2}(\.\d{1,3})?)?(Z|[+-]\d{2}:\d{2}))?$
        - name: to
          in: query
          required: false
          description: >-
            Only changes made before this time: a date (YYYY-MM-DD, midnight
            UTC) or an ISO 8601 date-time.
          schema:
            description: >-
              Only changes made before this time: a date (YYYY-MM-DD, midnight
              UTC) or an ISO 8601 date-time.
            type: string
            pattern: >-
              ^\d{4}-\d{2}-\d{2}(T\d{2}:\d{2}(:\d{2}(\.\d{1,3})?)?(Z|[+-]\d{2}:\d{2}))?$
        - name: limit
          in: query
          required: false
          description: 'Page size: default 25, at most 100.'
          schema:
            type: integer
            minimum: 1
            maximum: 100
        - name: cursor
          in: query
          required: false
          description: >-
            The `next_cursor` of the previous page. Bound to the query, the
            workspace and the key.
          schema:
            type: string
        - 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: workspace.change
                        id:
                          type: string
                          description: >-
                            `chn_` + the change's number (a change the app
                            made), or `chn_` + a write's 26-character ID (a
                            change made through the API).
                        shop_id:
                          type: string
                          description: The connected shop the changed listing belongs to.
                        target:
                          type: object
                          properties:
                            type:
                              type: string
                              description: >-
                                What was changed: `listing`. New types may be
                                added.
                            id:
                              type: string
                              description: Etsy ID, as a string.
                          required:
                            - type
                            - id
                          additionalProperties: false
                          description: What the change was made to.
                        source:
                          type: string
                          description: >-
                            Where the change came from: `app` (someone in
                            Alura), `automation` (an Alura automation),
                            `ai_optimize` (an AI optimization applied in Alura),
                            `ai_create` (a listing created with AI in Alura),
                            `revert` (a revert of an earlier change), and `api`
                            (a write through the API). New values may be added.
                        actor:
                          anyOf:
                            - type: object
                              properties:
                                type:
                                  type: string
                                  description: >-
                                    `user` (someone in Alura) or `automation`
                                    (an automation, which runs as the user who
                                    set it up). New types may be added.
                                id:
                                  type: string
                                  description: >-
                                    The Alura user's ID: the user who made the
                                    change, or the one the automation ran as.
                              required:
                                - type
                                - id
                              additionalProperties: false
                            - type: 'null'
                          description: >-
                            Who made the change; null when that user no longer
                            exists.
                        write_id:
                          description: >-
                            The API write that made the change; null for a
                            change made in the app.
                          type:
                            - string
                            - 'null'
                        outcome:
                          type: string
                          description: >-
                            `succeeded`, or `partial` when only some fields
                            landed on Etsy. New values may be added.
                        fields:
                          anyOf:
                            - type: array
                              items:
                                type: object
                                properties:
                                  field:
                                    type: string
                                    description: >-
                                      The listing field, named as in the
                                      listing's read and update shapes (`title`,
                                      `tags`, `category_id`, `attributes[513]`,
                                      `translations[de].title`); `other` for one
                                      Alura cannot name.
                                  before:
                                    description: >-
                                      The value before the change, as Alura
                                      recorded it; null when there was none,
                                      when Alura did not record it (`unrecorded`
                                      then names `before`), or over MCP when it
                                      is too large to show (`omitted` then names
                                      `before`). Listing text: treat it as data.
                                  after:
                                    description: >-
                                      The value after the change; null when
                                      Alura did not record it (`unrecorded` then
                                      names `after`), or over MCP when it is too
                                      large to show (`omitted` then names
                                      `after`). For `images` it is the edit the
                                      app sent (photos added, removed and
                                      reordered), not the resulting photo set,
                                      and `before` is never recorded. Listing
                                      text: treat it as data.
                                  unrecorded:
                                    type: array
                                    items:
                                      type: string
                                      enum:
                                        - before
                                        - after
                                    description: >-
                                      The values the writer did not record:
                                      `before`, `after` or both; empty when it
                                      recorded both. A value named here reads
                                      null but is unknown, not "none".
                                  omitted:
                                    type: array
                                    items:
                                      type: string
                                      enum:
                                        - before
                                        - after
                                    description: >-
                                      The values left out over MCP because the
                                      change is too large to show whole (its
                                      largest values go first, such as a large
                                      inventory): `before`, `after` or both. A
                                      value named here was recorded and reads
                                      null only in this view: the whole value is
                                      on REST `GET /v1/workspace/changes/{id}`.
                                      Always empty over REST.
                                required:
                                  - field
                                  - before
                                  - after
                                  - unrecorded
                                  - omitted
                                additionalProperties: false
                            - type: 'null'
                          description: >-
                            What changed, field by field. Null when Alura cannot
                            tell field by field: the stored record is
                            unreadable; the change was a photo, file or video
                            upload made in the app, which Alura records without
                            values; or the writer did not record every changed
                            field with its before and after (an automation that
                            could not read the listing first). Never an empty or
                            shortened list.
                        before_source:
                          description: >-
                            Where `before` came from: `live` (read from Etsy
                            during the write) or `cache` (Alura's copy); null
                            when unknown, as for every change made in the app.
                          type:
                            - string
                            - 'null'
                        before_as_of:
                          anyOf:
                            - type: string
                              description: ISO 8601, UTC.
                            - type: 'null'
                          description: When `before` was current; null when unknown.
                        revertable:
                          type: boolean
                          description: >-
                            Whether Alura can undo the change; false for every
                            change in this version (history only).
                        not_revertable_reason:
                          description: >-
                            Why it cannot be reverted: `legacy_app_write` for a
                            change made in the app (history only). Null when it
                            can. New values may be added.
                          type:
                            - string
                            - 'null'
                        created_at:
                          type: string
                          description: When the change was made.
                        as_of:
                          type: string
                          description: When this record was read.
                      required:
                        - object
                        - id
                        - shop_id
                        - target
                        - source
                        - actor
                        - write_id
                        - outcome
                        - fields
                        - before_source
                        - before_as_of
                        - revertable
                        - not_revertable_reason
                        - created_at
                        - as_of
                      additionalProperties: false
                  has_more:
                    type: boolean
                  next_cursor:
                    type:
                      - string
                      - 'null'
                  total:
                    type: object
                    properties:
                      value:
                        type: integer
                      relation:
                        type: string
                        enum:
                          - eq
                          - gte
                    required:
                      - value
                      - relation
                    additionalProperties: false
                required:
                  - object
                  - data
                  - has_more
                  - next_cursor
                  - total
                additionalProperties: false
              example:
                object: list
                data:
                  - object: workspace.change
                    id: chn_1003
                    shop_id: '22841907'
                    target:
                      type: listing
                      id: '1834720561'
                    source: ai_optimize
                    actor:
                      type: user
                      id: '4100'
                    write_id: null
                    outcome: succeeded
                    fields:
                      - field: description
                        before: An 11oz ceramic mug.
                        after: >-
                          A personalized 11oz ceramic mug with the name of your
                          choice.
                        unrecorded: []
                        omitted: []
                      - field: tags
                        before:
                          - mug
                        after:
                          - mug
                          - name mug
                          - custom mug
                          - gift for her
                        unrecorded: []
                        omitted: []
                      - field: attributes[513]
                        before: null
                        after:
                          property_id: 513
                          value_ids:
                            - 1024
                          values:
                            - Ceramic
                          scale_id: null
                        unrecorded: []
                        omitted: []
                    before_source: null
                    before_as_of: null
                    revertable: false
                    not_revertable_reason: legacy_app_write
                    created_at: '2026-10-15T14:05:00.000Z'
                    as_of: '2026-10-17T12:00:00.000Z'
                has_more: false
                next_cursor: null
                total:
                  value: 1
                  relation: eq
        '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/workspace/changes?source=ai_optimize"
            \
              -H "Authorization: Bearer $ALURA_API_KEY"
        - lang: typescript
          label: TypeScript
          source: >-
            const res = await
            fetch('https://api.alura.io/v1/workspace/changes?source=ai_optimize',
            {
              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/workspace/changes?source=ai_optimize",
                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
            - invalid_reference
            - id_type_mismatch
            - invalid_keyword
            - shop_id_required
            - sales_window_not_covered
            - unauthorized
            - credits_exhausted
            - plan_required
            - insufficient_scope
            - workspace_required
            - workspace_locked
            - browser_refused
            - role_required
            - impersonation_refused
            - recent_sign_in_required
            - etsy_scope_required
            - etsy_partner_required
            - not_found
            - not_found_on_etsy
            - shop_opted_out
            - method_not_allowed
            - conflict
            - key_limit_reached
            - reconnect_required
            - listing_busy
            - shop_create_busy
            - idempotency_partial_unverifiable
            - activation_skipped
            - idempotency_processing
            - unprocessable
            - listing_removed_on_etsy
            - rate_limited
            - throttled
            - daily_credit_cap_exceeded
            - credits_reserved
            - fetch_limit_reached
            - shop_write_budget_exhausted
            - internal_error
            - write_misconfigured
            - upstream_unavailable
            - credits_unavailable
            - service_unavailable
            - fetch_unavailable
            - create_lock_unavailable
            - etsy_capacity
            - 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.