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

# Check a coupon code

> Check whether an individual code from a Shopify or BigCommerce pool has
been redeemed, read live from the connected store's per-code usage
counter (Privy stores no redemption events).

This is a counter, not an event log: `usage_count` says how many times
the store has accepted the code, but redemption dates, order ids, and
customer attribution are not available — every response repeats this in
an in-band `note`. Manual pools have no store-side counter and return
`422 unsupported_coupon_type`.

A spot check for individual codes — there is no bulk sweep; asking
"which of my thousands of codes were redeemed" is not served by this
endpoint.

Membership semantics: a master pool's single code is matched exactly
(case-insensitively) before the store is asked. Unique-pool codes are
resolved against the store directly — Privy stores no per-code linkage
for platform pools, so a code from one of your OTHER pools would still
resolve; the check never crosses accounts.

**Required scope:** `coupons_read`




## OpenAPI

````yaml openapi/privy-api.yaml GET /coupons/{id}/codes/{code}
openapi: 3.1.0
info:
  title: Privy API
  version: '1.0'
  description: >
    The Privy API lets you programmatically manage your contact list and read
    what you have set up in Privy.

    Create, update, unsubscribe, and remove contacts; report orders;

    and read your campaigns, flows, segments, orders, store products, coupon
    pools,

    performance reports, and account setup.
servers:
  - url: https://api.privy.com/v1
    description: Production
security:
  - bearerAuth: []
tags:
  - name: Account
    description: Retrieve information about the authenticated Privy account.
  - name: Contacts
    description: Manage your contact list.
  - name: Imports
    description: >-
      Read your contact import history — CSV uploads, connected-provider syncs,
      and SMS consent imports.
  - name: Campaigns
    description: >-
      Read your message campaigns — email and SMS newsletters, plus the messages
      your flows send.
  - name: Displays
    description: >-
      Read your on-site displays (popups, flyouts, banners, embedded forms,
      landing pages).
  - name: Coupons
    description: Read your coupon pools, their code inventory, and individual codes.
  - name: Reports
    description: >-
      Read performance reporting — signups, views, conversion rates, and
      attributed revenue — for your business, displays, and flows.
  - name: Flows
    description: Read your automation flows and their configuration.
  - name: Segments
    description: Read your customer segments and their membership.
  - name: Orders
    description: Report orders placed in your store and read your order history.
  - name: Products
    description: Read the product catalog and collections of your connected store.
  - name: Events
    description: Ingest custom events to trigger Flows and other automations.
paths:
  /coupons/{id}/codes/{code}:
    get:
      tags:
        - Coupons
      summary: Check a coupon code
      description: |
        Check whether an individual code from a Shopify or BigCommerce pool has
        been redeemed, read live from the connected store's per-code usage
        counter (Privy stores no redemption events).

        This is a counter, not an event log: `usage_count` says how many times
        the store has accepted the code, but redemption dates, order ids, and
        customer attribution are not available — every response repeats this in
        an in-band `note`. Manual pools have no store-side counter and return
        `422 unsupported_coupon_type`.

        A spot check for individual codes — there is no bulk sweep; asking
        "which of my thousands of codes were redeemed" is not served by this
        endpoint.

        Membership semantics: a master pool's single code is matched exactly
        (case-insensitively) before the store is asked. Unique-pool codes are
        resolved against the store directly — Privy stores no per-code linkage
        for platform pools, so a code from one of your OTHER pools would still
        resolve; the check never crosses accounts.

        **Required scope:** `coupons_read`
      operationId: getCouponCode
      parameters:
        - $ref: '#/components/parameters/AccountIdParam'
        - name: id
          in: path
          required: true
          description: >-
            The coupon pool's unique identifier (returned as `id` in coupon
            responses). Ids are opaque public strings — a numeric id from a
            Privy dashboard URL is not a valid API id and will 404; list coupons
            and match by title instead.
          schema:
            type: string
          example: Xk2fW9qLpV
        - name: code
          in: path
          required: true
          description: The coupon code to check, URL-encoded. Matched case-insensitively.
          schema:
            type: string
          example: VIP4X9K2
      responses:
        '200':
          description: The code's store-side usage status.
          content:
            application/json:
              schema:
                type: object
                properties:
                  data:
                    type: object
                    properties:
                      code:
                        type: string
                        description: The code in the store's canonical casing.
                        example: VIP4X9K2
                      redeemed:
                        type: boolean
                        description: Whether the store's usage counter is above zero.
                        example: true
                      usage_count:
                        type: integer
                        description: How many times the store has accepted the code.
                        example: 1
                  note:
                    type: string
                    description: >-
                      Fixed caveat that this is a usage counter, not an event
                      log.
              example:
                data:
                  code: VIP4X9K2
                  redeemed: true
                  usage_count: 1
                note: >-
                  redeemed and usage_count come from the connected store's usage
                  counter, not an event log: redemption dates, order ids, and
                  customer attribution are not available.
        '401':
          $ref: '#/components/responses/Unauthorized'
        '403':
          $ref: '#/components/responses/InsufficientScope'
        '404':
          description: >-
            The pool id is unknown, the code is not the master pool's code, the
            store no longer knows the code, or the pool's store connection is
            gone (code `no_connected_store`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: not_found
                  message: Code not found on the connected store
        '422':
          description: Manual pools have no store-side usage counter to check.
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: unsupported_coupon_type
                  message: >-
                    Manual coupon pools have no store-side usage counter to
                    check.
        '429':
          description: >-
            Rate limit exceeded — either Privy's API rate limit (code
            `rate_limited`) or the connected store's own quota passed through
            (code `store_rate_limited`).
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ErrorResponse'
              example:
                error:
                  code: store_rate_limited
                  message: >-
                    The connected store is rate limiting requests. Try again
                    shortly.
        '502':
          $ref: '#/components/responses/StoreUnavailable'
      security:
        - bearerAuth: []
components:
  parameters:
    AccountIdParam:
      name: Privy-Account-Id
      in: header
      required: false
      description: >
        Target a subaccount instead of the main connected account.

        Pass a subaccount `id` from get_account's `subaccounts` list. Only
        direct subaccounts

        of the connected account are reachable — omit this for the main account
        itself.
      schema:
        type: string
      example: S1U2B3A4C5C6T7
  responses:
    Unauthorized:
      description: Missing or invalid bearer token.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: unauthorized
              message: Bearer token is missing or invalid
    InsufficientScope:
      description: Token lacks the required scope for this endpoint.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: insufficient_scope
              message: Token does not have the required scope
    StoreUnavailable:
      description: >-
        The connected store's API could not be reached or returned an error.
        Retry shortly.
      content:
        application/json:
          schema:
            $ref: '#/components/schemas/ErrorResponse'
          example:
            error:
              code: store_unavailable
              message: The connected store could not be reached. Try again shortly.
  schemas:
    ErrorResponse:
      type: object
      properties:
        error:
          type: object
          required:
            - code
            - message
          properties:
            code:
              type: string
              enum:
                - invalid_client
                - invalid_scope
                - unauthorized
                - insufficient_scope
                - paid_plan_required
                - api_access_required
                - not_found
                - no_connected_store
                - conflict
                - contacts_not_ready
                - validation_failed
                - rate_limited
                - store_unavailable
              example: validation_failed
            message:
              type: string
              example: One or more fields are invalid
            details:
              type: array
              items:
                type: object
                properties:
                  field:
                    type: string
                    example: email
                  message:
                    type: string
                    example: is required
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: API token or OAuth access token
      description: >
        Send either an API token or an OAuth access token as

        `Authorization: Bearer <token>`. See the Authentication page for
        details.

````