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

# Subscription Info

> Get user subscription information

## Endpoint

```
GET /api/subscription
```

## Overview

Retrieves subscription information for the authenticated user's DROP service. Fetches data from Polar API and formats it for display.

## Request

Requires authentication via Bearer token. User must have an active DROP service entitlement with a Polar subscription.

## Response

<ResponseField name="id" type="string">
  Polar subscription ID
</ResponseField>

<ResponseField name="status" type="string">
  Subscription status (e.g., "active", "canceled")
</ResponseField>

<ResponseField name="currentPeriodStart" type="number">
  Current billing period start timestamp (Unix seconds)
</ResponseField>

<ResponseField name="currentPeriodEnd" type="number">
  Current billing period end timestamp (Unix seconds)
</ResponseField>

<ResponseField name="cancelAtPeriodEnd" type="boolean">
  Whether subscription will cancel at period end
</ResponseField>

<ResponseField name="plan" type="string">
  Plan name from metadata
</ResponseField>

<ResponseField name="billingCycle" type="string">
  Billing cycle (e.g., "monthly", "yearly")
</ResponseField>

<ResponseField name="price" type="object">
  Price information

  <Expandable title="Price Object">
    <ResponseField name="amount" type="number">
      Price amount in PLN
    </ResponseField>

    <ResponseField name="currency" type="string">
      Currency code: "pln"
    </ResponseField>

    <ResponseField name="interval" type="string">
      Billing interval (e.g., "month")
    </ResponseField>
  </Expandable>
</ResponseField>

<ResponseField name="product" type="object">
  Product information

  <Expandable title="Product Object">
    <ResponseField name="name" type="string">
      Product name
    </ResponseField>
  </Expandable>
</ResponseField>

## Implementation Details

### Code Reference

```7:67:nullpass_clean/src/app/api/subscription/route.ts theme={null}
export async function GET(request: NextRequest) {
  const corsResponse = handleCors(request)
  if (corsResponse) return corsResponse

  const blocked = await protectRoute(request)
  if (blocked) return blocked

  const auth = await requireAuth(request)
  if ('error' in auth) return auth.error

  try {
    const entitlement = await prisma.userServiceEntitlement.findUnique({
      where: {
        userId_service: {
          userId: auth.userId,
          service: 'DROP',
        },
      },
      select: { polarSubscriptionId: true },
    })

    if (!entitlement?.polarSubscriptionId) {
      return errorResponse('No active subscription', 404, request.headers.get('origin'))
    }

    const response = await fetch(`https://api.polar.sh/v1/subscriptions/${entitlement.polarSubscriptionId}`, {
      headers: {
        'Authorization': `Bearer ${process.env.POLAR_ACCESS_TOKEN}`,
        'Content-Type': 'application/json'
      }
    })

    if (!response.ok) {
      return errorResponse('Failed to fetch subscription data', 500, request.headers.get('origin'))
    }

    const subscription = await response.json()
    
    return jsonResponse({
      id: subscription.id,
      status: subscription.status,
      currentPeriodStart: subscription.current_period_start ? new Date(subscription.current_period_start).getTime() / 1000 : 0,
      currentPeriodEnd: subscription.current_period_end ? new Date(subscription.current_period_end).getTime() / 1000 : 0,
      cancelAtPeriodEnd: subscription.cancel_at_period_end,
      plan: subscription.metadata?.plan || 'unknown',
      billingCycle: subscription.metadata?.billingCycle || 'monthly',
      price: {
        amount: subscription.price?.price_currency === 'usd' 
          ? Math.round(((subscription.price?.price_amount || 0) / 100) * 4)
          : (subscription.price?.price_amount || 0) / 100,
        currency: 'pln',
        interval: subscription.price?.recurring_interval || 'month'
      },
      product: {
        name: subscription.product?.name || 'Premium'
      }
    }, 200, request.headers.get('origin'))
  } catch (error) {
    return errorResponse('Internal server error', 500, request.headers.get('origin'))
  }
}
```

## Status Codes

<ResponseField name="200" type="OK">
  Success
</ResponseField>

<ResponseField name="401" type="Unauthorized">
  Missing or invalid authentication token
</ResponseField>

<ResponseField name="404" type="Not Found">
  No active subscription found
</ResponseField>

<ResponseField name="500" type="Internal Server Error">
  Failed to fetch subscription data from Polar
</ResponseField>

## Example Request

```bash theme={null}
curl -X GET https://auth.nullpass.xyz/api/subscription \
  -H "Authorization: Bearer YOUR_TOKEN"
```

## Example Response

```json theme={null}
{
  "id": "sub_1234567890",
  "status": "active",
  "currentPeriodStart": 1704067200,
  "currentPeriodEnd": 1706659200,
  "cancelAtPeriodEnd": false,
  "plan": "pro",
  "billingCycle": "monthly",
  "price": {
    "amount": 40,
    "currency": "pln",
    "interval": "month"
  },
  "product": {
    "name": "DROP Pro"
  }
}
```

## Notes

* Only works for DROP service subscriptions
* Requires active Polar subscription ID
* Price is converted to PLN (USD prices multiplied by 4)
* Timestamps are returned as Unix seconds


## OpenAPI

````yaml GET /subscription
openapi: 3.1.0
info:
  title: Null Pass API
  description: >-
    Internal API documentation for Null Pass authentication and service
    management system
  version: 1.0.0
servers:
  - url: https://auth.nullpass.xyz/api
security: []
paths:
  /subscription:
    get:
      tags:
        - Account
      summary: Get Subscription
      description: Get user subscription information
      responses:
        '200':
          description: Subscription information
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Subscription'
      security:
        - bearerAuth: []
components:
  schemas:
    Subscription:
      type: object
      properties:
        id:
          type: string
        status:
          type: string
        currentPeriodStart:
          type: integer
        currentPeriodEnd:
          type: integer
        cancelAtPeriodEnd:
          type: boolean
        plan:
          type: string
        billingCycle:
          type: string
        price:
          type: object
          properties:
            amount:
              type: number
            currency:
              type: string
            interval:
              type: string
        product:
          type: object
          properties:
            name:
              type: string
  securitySchemes:
    bearerAuth:
      type: http
      scheme: bearer
      bearerFormat: JWT

````