BIO.RE
Creator

Get Dashboard Login Link

One-shot login URL for the creator's Stripe Express dashboard. Requires the account to be ACTIVE. Use to deep-link into payouts, payment methods, and settings.

POST /api/v1/creators/stripe-connect/dashboard-link — 🔑 Bearer · Rate limit: 10 req / hour

Returns a single-use Stripe Express dashboard login URL for the creator. Use to deep-link from the platform UI into the creator's Stripe dashboard (where they manage payouts, view balances, update payment methods, etc.) without making them log in to Stripe directly.

Active-only. Dashboard links are gated on stripeAccountStatus === 'ACTIVE'. Pending / restricted / disabled accounts can't access the dashboard yet — show the user the onboarding flow instead. Surface "Finish setting up your account" UI when you see creator.stripe.not_active.

Single-use. Stripe login links work for one redirect — fetch a new one every time the user clicks "Manage payouts" rather than caching the URL. The URL becomes invalid after first use or after a short timeout.

Request

No body, no params. Identity comes from the bearer token.

HeaderRequiredNotes
Authorization: Bearer <accessToken>JWT from POST /auth/login

Response

200 OKApiResponseOf<StripeConnectDashboardLinkResponseDto>

{
  "success": true,
  "data": {
    "url": "https://connect.stripe.com/express/..."
  }
}
FieldTypeNotes
urlstringOne-shot Stripe Express dashboard login URL. Render into a button click handler that immediately redirects — don't store.

Errors

HTTPcode / i18nKeyReason
400creator.stripe.account_not_foundNo stripeAccountId on the creator
400creator.stripe.not_activestripeAccountStatus !== 'ACTIVE' — account hasn't finished onboarding yet
400creator.stripe.service_unavailableStripe SDK is not configured
401(guard)Missing / invalid bearer token
404creator.stripe.not_creatorNo CreatorProfile for this user
429(throttle)Rate limit exceeded (10 req/hour)

Side effects

  1. Lookup CreatorProfile; throw not_creator if missing.
  2. Assert stripeAccountId is non-null; otherwise account_not_found.
  3. Assert stripeAccountStatus === ACTIVE; otherwise not_active.
  4. Call stripe.accounts.createLoginLink(stripeAccountId).
  5. Return { url: loginLink.url }. No DB writes.

Code samples

curl -X POST https://api.bio.re/api/v1/creators/stripe-connect/dashboard-link \
  -H "Authorization: Bearer $ACCESS_TOKEN"
async function getDashboardLink(accessToken: string): Promise<string> {
  const res = await fetch('https://api.bio.re/api/v1/creators/stripe-connect/dashboard-link', {
    method: 'POST',
    headers: { Authorization: `Bearer ${accessToken}` },
  });
  const json = await res.json();
  if (!res.ok || !json.success) {
    throw Object.assign(new Error(json?.error?.message ?? 'Dashboard link failed'), {
      code: json?.error?.code,
    });
  }
  return json.data.url as string;
}

// Usage: fetch on-demand, redirect immediately
async function openStripeDashboard(accessToken: string) {
  const url = await getDashboardLink(accessToken);
  window.location.assign(url);
}
import { useMutation } from '@tanstack/react-query';

export function useGetDashboardLink() {
  // Mutation, not query — single-use URL, never cache
  return useMutation({
    mutationFn: async () => {
      const res = await fetch('/api/v1/creators/stripe-connect/dashboard-link', { method: 'POST' });
      const json = await res.json();
      if (!res.ok || !json.success) {
        throw Object.assign(new Error(json?.error?.message ?? 'Dashboard link failed'), {
          code: json?.error?.code,
          i18nKey: json?.error?.i18nKey,
        });
      }
      return json.data.url as string;
    },
  });
}

Try it

POST
/api/v1/creators/stripe-connect/dashboard-link
AuthorizationBearer <token>

In: header

Response Body

application/json

application/json

curl -X POST "https://loading/api/v1/creators/stripe-connect/dashboard-link"
{
  "success": true,
  "data": {
    "url": "string"
  }
}
{
  "success": false,
  "error": {
    "code": "AUTH_UNAUTHORIZED",
    "message": "Invalid credentials",
    "i18nKey": "auth.login.invalid_credentials",
    "i18nVars": {
      "field": "email"
    },
    "details": [
      {
        "message": "email must be an email"
      }
    ],
    "correlationId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
  }
}

Source

SourcePathLines
Controllerapps/api-core/src/modules/creator/stripe-connect.controller.ts44–51 (dashboardLink)
DTO (response)apps/api-core/src/modules/creator/dto/stripe-connect-response.dto.ts48–51 (StripeConnectDashboardLinkResponseDto)
Serviceapps/api-core/src/modules/creator/stripe-connect.service.ts183–207 (getDashboardLink)
Stripe providerapps/api-core/src/modules/payment/stripe.provider.tsrequireStripe()
Prisma modelpackages/prisma/prisma/schema.prismaCreatorProfile.stripeAccountId, CreatorProfile.stripeAccountStatus (enum StripeAccountStatus.ACTIVE)

On this page