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

# Access

> Check whether a customer can access a product

The access endpoint tells you whether a customer is entitled to use a product — either because they have an active subscription or because they made a confirmed one-time payment. This is the check the AI SDK, LangChain, and UploadThing adapters run automatically, but you can call it directly from your own server-side logic.

## Check access

`GET /customers/{customer_id}/access/{product_id}`

Returns whether the customer has access to the product and the reason why.

```bash theme={null}
curl https://api.stellartools.dev/customers/cus_01jx.../access/prod_01jx... \
  -H "x-api-key: YOUR_API_KEY"
```

### Response

```json theme={null}
{
  "has_access": true,
  "grant": {
    "type": "subscription",
    "subscription_id": "sub_01jx...",
    "status": "active"
  }
}
```

```json theme={null}
{
  "has_access": true,
  "grant": {
    "type": "one_time",
    "payment_id": "pay_01jx..."
  }
}
```

```json theme={null}
{
  "has_access": false,
  "grant": null
}
```

<ResponseField name="has_access" type="boolean">
  Whether the customer is entitled to use the product.
</ResponseField>

<ResponseField name="grant" type="object | null">
  The reason access was granted. `null` when `has_access` is false.

  <Expandable title="grant fields">
    <ResponseField name="type" type="&#x22;subscription&#x22; | &#x22;one_time&#x22;">
      What kind of entitlement granted access.
    </ResponseField>

    <ResponseField name="subscription_id" type="string">
      Present when `type` is `"subscription"`. The subscription that is active.
    </ResponseField>

    <ResponseField name="status" type="string">
      Present when `type` is `"subscription"`. The subscription status (`active`, `trialing`, or `paused`). Subscriptions scheduled to cancel remain `active` until `current_period_end`.
    </ResponseField>

    <ResponseField name="payment_id" type="string">
      Present when `type` is `"one_time"`. The confirmed payment that granted access.
    </ResponseField>
  </Expandable>
</ResponseField>

## SDK usage

The `@stellartools/core` SDK exposes this as `customers.access.verify(customerId, productId)`:

```ts theme={null}
import { StellarTools } from "@stellartools/core";

const stellar = new StellarTools({ api_key: process.env.STELLAR_TOOLS_API_KEY! });

const { has_access, grant } = await stellar.customers.access.verify("cus_xxx", "prod_xxx");

if (!has_access) {
  throw new Error("Customer does not have access to this product");
}

// grant.type tells you whether it's a subscription or one-time payment
if (grant?.type === "subscription") {
  console.log("Active subscription:", grant.subscription_id);
}
```
