---
title: "Retrieve a product"
method: GET
path: "/v1/products/{product_id}"
tags: ["Products"]
---

# Retrieve a product

`GET /v1/products/{product_id}`

Retrieves a single product by its ID. Requires the `products:read` scope.

## Path parameters

- `product_id` string, required

## Response `200`

Success

- ProductResponse
  - `id` string — Unique identifier for the product, prefixed with `prod_`.
  - `organization_id` string — The organization that owns the product.
  - `name` string — Display name of the product.
  - `description` string, nullable — Optional description of the product. `null` when not set.
  - `price` PriceResponse
    - `currency` string
    - `price_type` 'fixed' | 'free' | 'custom' — How the product is priced. `fixed`: a set amount, given in `amount`. `free`: no charge. `custom`: the customer pays what they want, bounded by `minimum_amount` and `maximum_amount` with an optional `preset_amount` suggestion.
    - `amount` string — Price in the primary currency as a decimal string.
    - `preset_amount` string, nullable — Suggested amount prefilled at checkout for a custom price, as a decimal string. Only used when `price_type` is `custom`.
    - `minimum_amount` string, nullable — Minimum the customer must pay. Present only when `price_type` is `custom`.
    - `maximum_amount` string, nullable — Maximum the customer may pay. Present only when `price_type` is `custom`.
    - `currency_options` CurrencyOptionResponse[]
      - `currency` string
      - `amount` string
      - `minimum_amount` string, nullable
      - `maximum_amount` string, nullable
  - `status` 'active' | 'archived' — Status of the product. `active`: Live and available for use in checkouts and subscriptions. `archived`: Retired. Kept for reference but not available for new purchases.
  - `metadata` object, nullable — Your own key-value data attached to the product, returned unchanged.
  - `media` MediaItemResponse[] — Media items (images) attached to the product. Empty when none are set.
    - `id` string
    - `url` string, nullable
    - `file_name` string
    - `mime_type` string
    - `file_size_bytes` integer
    - `created_at` string, date-time
  - `actor_id` string — Identifier of the user or key that created the product.
  - `created_at` string, date-time — ISO 8601 timestamp when the product was created.
  - `updated_at` string, date-time — ISO 8601 timestamp when the product was last updated.
  - `archived_at` string, date-time, nullable — When set, the product is archived and cannot be used in new checkouts. `null` while the product is active.
  - `billing_cycle` SubscriptionCadence
    - `interval` 'day' | 'week' | 'month' | 'year' — Unit of time for each billing cycle. `day`: billed daily. `week`: billed weekly. `month`: billed monthly. `year`: billed yearly.
    - `frequency` integer — Number of intervals per cycle. For example, `interval` `month` with `frequency` `3` bills every three months.
  - `trial_period` TrialPeriod — The length of the free trial before the first charge, expressed as a count of time units. For example, `{ "interval": "day", "frequency": 14 }` is a 14-day trial.
    - `interval` 'day' | 'week' | 'month' | 'year', required — The unit of time the trial is measured in: `day`, `week`, `month`, or `year`.
    - `frequency` integer, required — How many `interval` units the trial lasts. For example, `interval` `day` with `frequency` `14` is a 14-day trial.
  - `prices` object[] — All prices configured on the product, one per currency. Each has `currency`, `amount`, optional `minimum_amount` and `maximum_amount`, and `is_default`.
  - `total_payments` integer — Running count of completed payments for this product. Starts at `0` and increments as customers pay.
  - `total_amount` string — Running total collected for this product, as a decimal string in the product currency. Starts at `"0.00"`.

## Other responses

- `401` — Unauthorized - Invalid, missing, or expired API key. Verify your API key is correctly formatted and included in the Authorization header as `Bearer sk_sandbox_...` or `Bearer sk_live_...`. Check that your key hasn't been revoked.
- `403` — Forbidden - API key does not have permission for the requested resource. Verify you're using the correct organization's API key and that you're not trying to access another organization's data.
- `404` — Not Found - The requested resource does not exist. Verify the resource ID is correct and that it belongs to your organization.

---

[API](https://skmtc.dev/bachs/apis/bachs-api.md) · [All operations](https://skmtc.dev/bachs/apis/bachs-api/llms.txt) · [OpenAPI document](https://skmtc-service-production.skmtc.workers.dev/v1/apis/bachs/bachs-api/revisions/f29efa8a22df/schema)
