# /api/webhooks/billing/stripe (management)

Source-derived management endpoint contract, authentication, request validation, responses, and errors.

Source: https://docs.minds.sh/docs/api/platform/reference/management--api-webhooks-billing-stripe



This is the **management** service route. Its origin and authentication are described in [Platform API overview](/docs/api/platform) and [Authentication](/docs/api/platform/authentication). A path shared by another service is a different endpoint.

| Property                       | Contract                                                                 |
| ------------------------------ | ------------------------------------------------------------------------ |
| Methods                        | POST, GET                                                                |
| Path                           | `/api/webhooks/billing/stripe`                                           |
| Path parameters                | None                                                                     |
| Query parameters read in route | None read directly; schema validation below may define additional fields |
| Headers read in route          | `stripe-signature`                                                       |

## Authentication and access [#authentication-and-access]

Webhook-specific signature or verification handler; not a customer bearer-token endpoint. See the handler and signing setup.

## Method behavior [#method-behavior]

The handler excerpt preserves field validation, response envelopes, cookie changes, and exception branches. Values returned by service helpers retain their named response type above; for passthrough routes, the upstream response is authoritative.

### POST [#post]

```typescript
export async function POST(request: Request) {
  if (!process.env.STRIPE_WEBHOOK_SECRET) {
    console.error('[billing] STRIPE_WEBHOOK_SECRET not configured')
    return NextResponse.json(
      { error: 'Stripe webhook not configured' },
      { status: 503 }
    )
  }

  const signature = request.headers.get('stripe-signature')
  if (!signature) {
    return NextResponse.json(
      { error: 'Missing stripe-signature header' },
      { status: 400 }
    )
  }

  const body = await request.text()

  let event
  try {
    event = verifyStripeWebhook(body, signature)
  } catch (error) {
    const message = error instanceof Error ? error.message : 'Invalid signature'
    return NextResponse.json({ error: message }, { status: 400 })
  }

  try {
    await handleStripeWebhook(event)
  } catch (error) {
    console.error('[billing] Stripe webhook processing failed:', error)
    return NextResponse.json(
      { error: 'Webhook processing failed' },
      { status: 500 }
    )
  }

  return NextResponse.json({ received: true }, { status: 200 })
}
```

Source: `minds-ui/apps/api-service/app/api/webhooks/billing/stripe/route.ts:14`.

### GET [#get]

```typescript
export async function GET() {
  return NextResponse.json({
    status: 'active',
    webhook: 'stripe',
    timestamp: new Date().toISOString(),
  })
}
```

Source: `minds-ui/apps/api-service/app/api/webhooks/billing/stripe/route.ts:54`.

## Response and error branches [#response-and-error-branches]

Literal HTTP statuses in the route: 200, 400, 500, 503. Shared management error classes are defined in [Errors and responses](/docs/api/platform/errors).

```typescript
NextResponse.json(
      { error: 'Stripe webhook not configured' },
      { status: 503 }
    )
```

Source: `minds-ui/apps/api-service/app/api/webhooks/billing/stripe/route.ts:17`.

```typescript
NextResponse.json(
      { error: 'Missing stripe-signature header' },
      { status: 400 }
    )
```

Source: `minds-ui/apps/api-service/app/api/webhooks/billing/stripe/route.ts:25`.

```typescript
NextResponse.json({ error: message }, { status: 400 })
```

Source: `minds-ui/apps/api-service/app/api/webhooks/billing/stripe/route.ts:38`.

```typescript
NextResponse.json(
      { error: 'Webhook processing failed' },
      { status: 500 }
    )
```

Source: `minds-ui/apps/api-service/app/api/webhooks/billing/stripe/route.ts:45`.

```typescript
NextResponse.json({ received: true }, { status: 200 })
```

Source: `minds-ui/apps/api-service/app/api/webhooks/billing/stripe/route.ts:51`.

```typescript
NextResponse.json({
    status: 'active',
    webhook: 'stripe',
    timestamp: new Date().toISOString(),
  })
```

Source: `minds-ui/apps/api-service/app/api/webhooks/billing/stripe/route.ts:55`.

## Service dependencies [#service-dependencies]

* `minds-ui/apps/api-service/lib/billing/webhooks.ts`

## Evidence [#evidence]

Generated from the local source snapshot on 2026-09-12. This page documents implemented code and does not certify a deployed service, permissions configuration, or successful provider operation.

Source file: `minds-ui/apps/api-service/app/api/webhooks/billing/stripe/route.ts`. SHA-256: `8edb8d286b581035ee7721720854e17647b3a40a6966a96c5dc33a9b2cbe3e81`.
