BIO.RE
Legal

Get Privacy Policy

Public read of the platform privacy policy. Content is admin-managed via ConfigService. Returns the body plus the last-updated timestamp.

GET /api/v1/legal/privacy — 🌐 Public

Returns the platform's privacy policy as a single document. Content is admin-managed via the legal.privacy_policy ConfigService key — when the admin updates the policy, the next read serves the new content. The lastUpdated timestamp comes from the config definition's updatedAt field, so the client can show "Last updated: ..." in the UI.

Admin-managed catalog. The policy text lives in ConfigService (admin → "Legal docs" pane). Versioning + change-tracking are platform concerns; this endpoint is read-only and always serves the current version. To track user consent across versions, see POST /users/consent (in the User module).

Default fallback when unconfigured. If the admin has never set legal.privacy_policy, the response carries content: 'Privacy policy not yet published.' and lastUpdated: null. Treat null lastUpdated as "no policy on file" and gate behavior accordingly (e.g. don't show the consent gate until a real policy exists).

Request

No body, no params, no headers required.

Response

200 OKApiResponseOf<LegalDocumentDto>

{
  "success": true,
  "data": {
    "content": "<p>Privacy Policy content...</p>",
    "lastUpdated": "2026-04-29T20:00:00.000Z"
  }
}
FieldTypeNotes
contentstringHTML body of the policy. Render with sanitization (e.g. DOMPurify) if untrusted-author surface is a concern; the platform admins are the only authors here, but defense-in-depth is fine.
lastUpdatedstring (ISO 8601) | nullTimestamp of the most recent admin update, derived from ConfigService.getEffective(key).definition.updatedAt. null when the config key has never been written.

Errors

This endpoint has no documented error responses beyond HTTP infrastructure failures (5xx). No 4xx — even unconfigured keys return 200 with the default fallback.

Side effects

  1. configService.getWithDefault('legal.privacy_policy', 'Privacy policy not yet published.').
  2. configService.getEffective('legal.privacy_policy'). If the result has definition.updatedAt, format as ISO; otherwise lastUpdated = null (with a warn log).
  3. Return { content, lastUpdated }. No mutations, no auth, no per-user state.

Code samples

curl https://api.bio.re/api/v1/legal/privacy
type LegalDocument = {
  content: string;
  lastUpdated: string | null;
};

async function getPrivacyPolicy(): Promise<LegalDocument> {
  const res = await fetch('https://api.bio.re/api/v1/legal/privacy');
  const json = await res.json();
  if (!res.ok || !json.success) {
    throw Object.assign(new Error(json?.error?.message ?? 'Privacy policy fetch failed'), {
      code: json?.error?.code,
    });
  }
  return json.data;
}
import { useQuery } from '@tanstack/react-query';

export const legalKeys = {
  privacy: () => ['legal', 'privacy'] as const,
};

export function usePrivacyPolicy() {
  return useQuery({
    queryKey: legalKeys.privacy(),
    queryFn: async () => {
      const res = await fetch('/api/v1/legal/privacy');
      const json = await res.json();
      if (!res.ok || !json.success) {
        throw Object.assign(new Error(json?.error?.message ?? 'Privacy policy fetch failed'), {
          code: json?.error?.code,
          i18nKey: json?.error?.i18nKey,
        });
      }
      return json.data as LegalDocument;
    },
    // Policies change rarely — cache aggressively
    staleTime: 60 * 60_000, // 1 hour
    gcTime: 24 * 60 * 60_000, // 1 day
  });
}

Try it

GET
/api/v1/legal/privacy

Response Body

application/json

curl -X GET "https://loading/api/v1/legal/privacy"
{
  "success": true,
  "data": {
    "content": "<p>Privacy Policy content...</p>",
    "lastUpdated": "2019-08-24T14:15:22Z"
  }
}

Source

SourcePathLines
Controllerapps/api-core/src/modules/legal/legal.controller.ts14–19 (getPrivacyPolicy)
DTO (response)apps/api-core/src/modules/legal/dto/legal-response.dto.ts7–13 (LegalDocumentDto)
Serviceapps/api-core/src/modules/legal/legal.service.ts10–20 (getPrivacyPolicy), 34–43 (getLastUpdated)
Config keys(admin-managed via ConfigService)legal.privacy_policy (string content; default 'Privacy policy not yet published.')

On this page