README.md

# Amazon Creators API - Elixir Client

An Elixir client library for the Amazon Creators API with automatic token
caching and management.

## Features

- ✅ Support for all Amazon regions (NA, EU, FE)
- ✅ Automatic OAuth token management with caching
- ✅ Token auto-refresh before expiration
- ✅ GenServer-based token cache for performance
- ✅ Comprehensive error handling
- ✅ Full test coverage
- ✅ Easy-to-use API

## Installation

Add `amazon_creators_api` to your list of dependencies in `mix.exs`:

```elixir
def deps do
  [
    {:amazon_creators_api, "~> 0.1.0"}
  ]
end
```

## Configuration

Set up your Amazon Creators API credentials as environment variables:

```bash
export CREATORS_API_CLIENT_ID="your_client_id"
export CREATORS_API_CLIENT_SECRET="your_client_secret"
export CREATORS_API_PARTNER_TAG="yourpartner-20"
```

## Usage

### Simple Usage (Recommended)

The easiest way to use the API is with `fetch_items/2`, which handles token management automatically:

```elixir
# Fetch a single item
opts = [
  region: :na,  # or :eu, :fe
  marketplace: "www.amazon.com",
  partner_tag: System.get_env("CREATORS_API_PARTNER_TAG"),
  client_id: System.get_env("CREATORS_API_CLIENT_ID"),
  client_secret: System.get_env("CREATORS_API_CLIENT_SECRET")
]

case AmazonCreatorsAPI.fetch_items("B09B2SBHQK", opts) do
  {:ok, %{"itemsResult" => %{"items" => items}}} ->
    Enum.each(items, fn item ->
      IO.puts(item["itemInfo"]["title"]["displayValue"])
      IO.puts(item["detailPageURL"])
    end)

  {:error, reason} ->
    IO.puts("Error: #{inspect(reason)}")
end
```

### Fetch Multiple Items

```elixir
asins = ["B09B2SBHQK", "B09B8V1LZ3", "B0BZTW3TCH"]

{:ok, %{"itemsResult" => %{"items" => items}}} =
  AmazonCreatorsAPI.fetch_items(asins, opts)

IO.puts("Fetched #{length(items)} items")
```

### European Marketplaces

```elixir
opts = [
  region: :eu,
  marketplace: "www.amazon.de",
  partner_tag: "yourpartner-21",
  client_id: System.get_env("CREATORS_API_CLIENT_ID"),
  client_secret: System.get_env("CREATORS_API_CLIENT_SECRET")
]

AmazonCreatorsAPI.fetch_items("B09B2SBHQK", opts)
```

### Custom Resources

By default, the API fetches common product information. You can specify custom resources:

```elixir
opts = [
  region: :na,
  marketplace: "www.amazon.com",
  partner_tag: "yourpartner-20",
  client_id: System.get_env("CREATORS_API_CLIENT_ID"),
  client_secret: System.get_env("CREATORS_API_CLIENT_SECRET"),
  resources: [
    "itemInfo.title",
    "itemInfo.features",
    "offersV2.listings.price",
    "images.primary.large"
  ]
]

AmazonCreatorsAPI.fetch_items("B09B2SBHQK", opts)
```

#### Available Resources

**Item Information:**

- `itemInfo.title`
- `itemInfo.features`
- `itemInfo.byLineInfo`
- `itemInfo.contentInfo`
- `itemInfo.contentRating`
- `itemInfo.classifications`
- `itemInfo.externalIds`
- `itemInfo.manufactureInfo`
- `itemInfo.productInfo`
- `itemInfo.technicalInfo`
- `itemInfo.tradeInInfo`

**Images:**

- `images.primary.small`
- `images.primary.medium`
- `images.primary.large`
- `images.primary.highRes`
- `images.variants.small`
- `images.variants.medium`
- `images.variants.large`
- `images.variants.highRes`

**Offers (Version 2):**

- `offersV2.listings.price`
- `offersV2.listings.availability`
- `offersV2.listings.condition`
- `offersV2.listings.dealDetails`
- `offersV2.listings.isBuyBoxWinner`
- `offersV2.listings.loyaltyPoints`
- `offersV2.listings.merchantInfo`
- `offersV2.listings.type`

**Browse Nodes:**

- `browseNodeInfo.browseNodes`
- `browseNodeInfo.browseNodes.ancestor`
- `browseNodeInfo.browseNodes.salesRank`
- `browseNodeInfo.websiteSalesRank`

**Customer Reviews:**

- `customerReviews.count`
- `customerReviews.starRating`

**Other:**

- `parentASIN`

### Manual Token Management

For advanced use cases where you want to manage tokens yourself:

```elixir
# Get a token (cached automatically)
{:ok, token_data} = AmazonCreatorsAPI.get_token(:na, client_id, client_secret)

# Use the token for multiple requests
{:ok, items1} = AmazonCreatorsAPI.get_items(
  "B09B2SBHQK",
  "www.amazon.com",
  "yourpartner-20",
  token_data["access_token"],
  token_data["version"]
)

{:ok, items2} = AmazonCreatorsAPI.get_items(
  "B09B8V1LZ3",
  "www.amazon.com",
  "yourpartner-20",
  token_data["access_token"],
  token_data["version"]
)
```

### Monitoring Token Cache

```elixir
# Get cache statistics
stats = AmazonCreatorsAPI.token_stats()
# => %{"na:your_client_id" => %{ttl_seconds: 3540, expires_at: 1735123456}}

# Clear cache (useful for testing or forcing refresh)
AmazonCreatorsAPI.clear_token_cache()
```

## Regions and Marketplaces

### North America (NA) - Version 2.1

- United States: `www.amazon.com`
- Canada: `www.amazon.ca`
- Mexico: `www.amazon.com.mx`
- Brazil: `www.amazon.com.br`

### Europe (EU) - Version 2.2

- United Kingdom: `www.amazon.co.uk`
- Germany: `www.amazon.de`
- France: `www.amazon.fr`
- Italy: `www.amazon.it`
- Spain: `www.amazon.es`
- Netherlands: `www.amazon.nl`
- Belgium: `www.amazon.com.be`
- Egypt: `www.amazon.eg`
- India: `www.amazon.in`
- Ireland: `www.amazon.ie`
- Poland: `www.amazon.pl`
- Saudi Arabia: `www.amazon.sa`
- Sweden: `www.amazon.se`
- Turkey: `www.amazon.com.tr`
- UAE: `www.amazon.ae`

### Far East (FE) - Version 2.3

- Japan: `www.amazon.co.jp`
- Singapore: `www.amazon.sg`
- Australia: `www.amazon.com.au`

## Error Handling

The API returns standard Elixir `{:ok, result}` or `{:error, reason}` tuples:

```elixir
case AmazonCreatorsAPI.fetch_items("INVALID_ASIN", opts) do
  {:ok, items} ->
    IO.inspect(items)

  {:error, :not_found} ->
    IO.puts("Item not found")

  {:error, :unauthorized} ->
    IO.puts("Invalid credentials")

  {:error, {:auth_failed, status, body}} ->
    IO.puts("Authentication failed: #{status}")

  {:error, {:http_error, status, body}} ->
    IO.puts("HTTP error: #{status}")

  {:error, {:request_failed, reason}} ->
    IO.puts("Request failed: #{inspect(reason)}")
end
```

## Token Caching

The library automatically caches authentication tokens using a GenServer.
Tokens are:

- Cached per region and client ID combination
- Automatically refreshed 60 seconds before expiration
- Reused across multiple API calls for better performance
- Thread-safe for concurrent applications

## Testing

Run the test suite:

```bash
mix test
```

Run tests with coverage:

```bash
mix coveralls
```

Run tests with detailed coverage:

```bash
mix coveralls.detail
```

## Architecture

The library consists of two main modules:

1. **AmazonCreatorsAPI**: Main API module with public functions
2. **AmazonCreatorsAPI.TokenManager**: GenServer that manages token caching

The TokenManager is automatically started as part of your application's
supervision tree.

## License

MIT License - see LICENSE file for details.

## Contributing

Contributions are welcome! Please feel free to submit a Pull Request.

## Support

For issues related to the Amazon Creators API itself, please refer to the official
[Amazon documentation](https://partnernet.amazon.de/creatorsapi/docs/en-us/concepts/common-request-headers-and-parameters).

For issues with this library, please open an issue on Codeberg.