Open-source project
hakanensari/vacuum avatar
hakanensari/vacuum

Vacuum and a Ruby wrapper for the Amazon Creators API

Amazon Creators API in Ruby

562 stars80 forksRubyMIT

At a glance

What is it?
Vacuum is a Ruby client for the Amazon Creators API, covering search, item lookup, browse nodes and product variations, with automatic token handling and a pluggable cache so a Rails app can share access tokens across processes. The interesting design point is that the API version also selects the region, so the same method works across North America, Europe and the Far East with one parameter.
Who is it for?
Vacuum is a good fit for a Ruby or Rails application that needs Amazon product data for affiliate content, because it covers the four operations the API exposes, handles the Cognito and Login with Amazon authentication differences, and lets a multi-process app share one token through a cache store.
Can I use it commercially?
Yes. MIT is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
Is it still maintained?
Activity is slowing. The repository last received commits 6 months ago.
What is it written in?
Mainly Ruby, according to GitHub's language statistics.

Answers come from the project's GitHub data, last synced on October 22, 2026, and from our analysis. They are not legal advice.

Editorial analysis

What Vacuum wraps, and for whom

Vacuum is a Ruby wrapper to the Amazon Creators API, which provides programmatic access to product information on the Amazon marketplaces. The name is a joke, and the README closes with a joke about it: Amazon is a $250 billion dollar company that reacts to you buying a vacuum by showing you more vacuums.

The scope is worth being precise about, because the name of the upstream API sets the expectation. The Creators API is a read surface over product catalogue data. The operations Vacuum exposes are GetBrowseNodes, GetItems, GetVariations and SearchItems, and every one of them takes a marketplace and a partner tag and returns product information. There is no order, no pricing negotiation and no inventory write path in the documented surface.

So the audience is a content or affiliate application: something that needs titles, images, prices, browse categories or search results for products, in order to link to them. The partner_tag parameter is the affiliate tracking identifier in the examples, formatted as yourtag-20, the shape the README examples all use.

The repository is a Ruby gem, with a gemspec, a lib/ directory, a spec/ directory, a Rakefile, a Gemfile and a.rubocop.yml at the root, plus a CHANGELOG.md. The licence is MIT.

The topics confirm the positioning: amazon, amazon-creators-api, amazon-product-advertising, product-advertising-api and ruby.

The project has no GitHub releases, and the last push was on 2026-04-21, so the version history lives in the CHANGELOG and on the gem registry rather than in tagged releases.

The client, the credentials and where the token comes from

Creating a client takes three parameters, and the version is the one that surprises people:

ruby
client = Vacuum.new(
  credential_id: "YOUR_CREDENTIAL_ID",
  credential_secret: "YOUR_CREDENTIAL_SECRET",
  version: "2.1"
)

The client handles authentication automatically and caches access tokens for one hour. That last detail is the reason the library exists at all rather than you writing four HTTP calls by hand: the token acquisition is the fiddly part, and doing it once per hour rather than once per request is the difference between a working integration and a rate-limited one.

The version string is not a client version. The README says the version determines which authentication endpoint to use: versions 2.x use Amazon Cognito, versions 3.x use Login with Amazon, which is LwA.

And here is the part that catches people out, because the version doubles as a region selector:

| Version | Region | |---------|--------| | `"2.1"` | North America | | `"2.2"` | Europe | | `"2.3"` | Far East | | `"3.1"` | North America | | `"3.2"` | Europe | | `"3.3"` | Far East |

So there are two axes collapsed into one string. The major version picks the authentication scheme, and the second digit picks the regional endpoint. There is no separate region parameter, which means a client for Europe and a client for the Far East cannot be the same object, and an application serving several marketplaces needs several clients, each with its own cached token.

That is a real constraint on the API design, but it is the API's, not Vacuum's. The wrapper's job is to expose it faithfully rather than hide it.

The four operations and the resources argument

Each operation requires a marketplace such as www.amazon.com and a partner_tag. Beyond those two, the shape of each call is driven by a resources list, and the documentation of the upstream API calls these resources because they determine how much data comes back and in what form.

GetBrowseNodes takes browse node identifiers and returns details about the specified node, like name, children and ancestors, depending on the resources specified in the request:

ruby
client.get_browse_nodes(
  marketplace: "www.amazon.com",
  partner_tag: "yourtag-20",
  browse_node_ids: ["283155", "3040"],
  resources: ["browseNodes.ancestor", "browseNodes.children"]
)

GetItems takes item identifiers and returns the item attributes based on the requested resources:

ruby
client.get_items(
  marketplace: "www.amazon.com",
  partner_tag: "yourtag-20",
  item_ids: ["B0199980K4", "B000HZD168"],
  resources: ["images.primary.small", "itemInfo.title", "itemInfo.features",
              "offersV2.listings.price", "parentASIN"]
)

GetVariations takes an ASIN and returns a set of items that are the same product but differ according to a consistent theme, for example size and color, which is the operation you want when you hold one variant and need the others:

ruby
client.get_variations(
  marketplace: "www.amazon.com",
  partner_tag: "yourtag-20",
  asin: "B00422MCUS",
  resources: ["itemInfo.title", "variationSummary.price.highestPrice",
              "variationSummary.price.lowestPrice",
              "variationSummary.variationDimension"]
)

And SearchItems searches for items on Amazon based on a search query, returning up to ten items per search request:

ruby
client.search_items(
  marketplace: "www.amazon.com",
  partner_tag: "yourtag-20",
  keywords: "harry potter"
)

The ten-item ceiling on search is the operational limit to design around. There is no pagination parameter in the documented call, so a search over a broad keyword returns one page of ten results, and anything more has to be assembled from narrower queries.

Parsing responses and sharing one token across processes

Every call returns a response object with a parse method, and the README is direct about what it does: parse the response body into a hash.

ruby
response.parse.dig("searchResult", "items")

The dig call is the idiomatic way to reach into the parsed structure, and the hash keys mirror the upstream JSON, which is worth knowing before you write any code against it: you are working with Amazon's response shape, not a normalised domain model. Vacuum parses, it does not translate. If you want a product object with sensible field names, you are writing that layer yourself, and the resources list is what determines which fields you will find.

The second part of the README is the Shared Token Cache, and it addresses a problem that only appears in production. By default, each client instance caches its own access token. In multi-process environments like Rails, you can share the token across processes by providing a cache store:

ruby
client = Vacuum.new(
  credential_id: "YOUR_CREDENTIAL_ID",
  credential_secret: "YOUR_CREDENTIAL_SECRET",
  version: "2.1",
  cache: Rails.cache
)

The requirement on the store is precise: the cache must respond to fetch(key, expires_in:, &block). That is a small interface, and it means anything that implements that one method works, whether it is a Rails cache, a Memcached client or a Redis wrapper.

The reason to care is straightforward. A Rails application running several worker processes, each with its own client instance, would otherwise each mint their own token. Sharing one token across the deployment reduces the number of authentication calls, which is exactly the kind of thing an API rate limit is sensitive to, and it makes the token lifetime meaningful rather than per-process.

The expires_in: keyword in the fetch signature is the library handing the one-hour lifetime to your cache, so the store decides how to expire it.

Development, tests and what the API tests need

The development section is brief, and the part worth reading is about credentials.

Clone the repo and install dependencies with bundle install. Run tests and Rubocop with bundle exec rake, which runs both in one command, so the style check and the test suite are not separable in the normal workflow.

The API tests are the interesting part. To run them, copy spec/credentials.yml.example to spec/credentials.yml and fill in your credentials.

That tells you the test suite hits the real API. The example file is the template, and the credentials are Amazon Creators API keys, which means running the suite requires an account with the API enabled, and that a test run makes live calls to Amazon. There is no recorded-fixture mode described, and no mention of a VCR or webmock layer in the README.

The consequence for a contributor is that a local `bundle exec rake` is not something you can run in a sandbox without credentials. The unit-level tests that do not need the network presumably still run, but the README does not separate them, so the practical instruction is that you need credentials to run the full command.

The repository layout supports that reading. The spec/ directory holds the tests, the.rubocop.yml holds the style configuration that the rake task enforces, the CHANGELOG.md is the release history, and there is an.editorconfig alongside the usual.gitignore and.github/ directory.

The absence of GitHub releases means the CHANGELOG is the only record of what changed, so it is the file to read when upgrading a pinned version.

Where Vacuum is the wrong tool

Four limits follow from what the upstream API is, and from how the wrapper is shaped.

The first is that this is a read surface. There is no operation for creating content, for reporting conversions, for managing a storefront or for anything transactional. If you need to check whether a link you published actually earned a commission, the Creators API as documented here will not answer that, and no amount of wrapper flexibility changes it.

The second is the search ceiling. Ten items per request with no documented pagination is a hard limit on the client side, and building a catalogue of any size around SearchItems means either narrow queries or the other three operations, which need identifiers you do not have yet.

The third is the region-bound client. Because the version parameter selects both the authentication scheme and the region, an application that serves several marketplaces holds several clients, each with its own token. That is workable, but it means the client object is not a singleton in the way a Rails initializer might otherwise make it, and the shared cache becomes correspondingly more valuable.

The fourth is the raw response shape. Vacuum parses the body into a hash and stops. There is no mapping to your domain objects, no error normalisation beyond whatever the upstream returns, and no retry or backoff behaviour described in the README. The dependencies list in the gemspec is small, which is consistent with a thin wrapper, but it also means the operational concerns of talking to a rate-limited public API are yours to handle.

For a script that needs a product title and an image URL, Vacuum is a good fit. For an application that treats Amazon as a data source it depends on, the thinness of the wrapper is something to plan around rather than discover later.

Editorial conclusion

Vacuum is a good fit for a Ruby or Rails application that needs Amazon product data for affiliate content, because it covers the four operations the API exposes, handles the Cognito and Login with Amazon authentication differences, and lets a multi-process app share one token through a cache store. It is a poor fit if you need to sell through the API rather than read from it, since the Creators API is a read-only product information surface, and a poor fit if you are on a Ruby version the gemspec does not support or if you need operation coverage beyond the four documented methods. Before adopting, confirm your marketplace and API version pair against the region table, since a 2.1 client talks to North America and a 3.1 client talks to North America through a different authentication endpoint, and set up a real cache store rather than relying on the per-instance default.

Frequently asked questions

What is the Vacuum Ruby gem?

It is a Ruby wrapper for the Amazon Creators API, which provides programmatic access to product information on the Amazon marketplaces. The client handles authentication automatically and caches access tokens for one hour.

How do I create a Vacuum client?

Pass credential_id, credential_secret and version to the constructor, for example `Vacuum.new(credential_id: "YOUR_CREDENTIAL_ID", credential_secret: "YOUR_CREDENTIAL_SECRET", version: "2.1")`. The version selects both the authentication endpoint and the region.

Which regions and API versions does Vacuum support?

Versions 2.x use Amazon Cognito and versions 3.x use Login with Amazon. The mapping is 2.1, 3.1 for North America, 2.2, 3.2 for Europe, and 2.3, 3.3 for the Far East.

How do I share an access token between Rails processes?

Pass a cache store to the client with the cache keyword, for example `cache: Rails.cache`. The store must respond to fetch(key, expires_in:, &block), which lets the one-hour token lifetime be managed by the store.

What operations does the Vacuum gem support?

GetBrowseNodes for browse node details, GetItems for item attributes, GetVariations for the other variants of a product, and SearchItems for keyword search, which returns up to ten items per request.

How do I run the Vacuum test suite?

Install dependencies with bundle install and run `bundle exec rake`, which runs the tests and Rubocop. The API tests need real credentials, so copy spec/credentials.yml.example to spec/credentials.yml and fill in your own.

Official sources

  1. hakanensari/vacuum on GitHub
  2. Issues
  3. License: MIT
  4. README
Add this badge to your README

If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.

Add this badge to your README

markdown
[![Hysen Labs](https://hysenlabs.com/badge/hakanensari-vacuum.svg)](https://hysenlabs.com/projects/hakanensari-vacuum)

Was this useful?