Skip to content

Legal pages and consent

The site renders your legal pages from text you supply and facts the file states, and asks a visitor before any tag you add loads.

A legal page, from your text to accepted

Filled: what a visitor and a Customer read. The words are always yours.

The generated site sets no cookie before sign-in, and counts visits without one. So by default it shows no consent prompt.

The portal's session cookie arrives with sign-in and does nothing else. Every tag you add in consent.tags waits for the visitor's yes to its category.

The visitorThe site
Opens a pageShows the prompt once, each category apart, refusing in one click as accepting does
Refuses, or sends the browser's privacy signal with gpcLoads no tag in that category, and asks again only after a new notice
AcceptsLoads the tags of the categories accepted
Changes its mindUses the footer link on every page, which withdraws at once

Each choice is a consent record: the categories, the notice version seen and the time, written as an Event.

Who writes what

APIs.Dev never writes a legal word for your product. You supply the text, and the file supplies the facts it states.

PageThe words, fromThe facts it prints, from the file
Termslegal.termsThe seller in legal.entity, the prices, the refund rule and the licence in terms
Privacy noticelegal.privacyEach data class kept, the processors, where the data lives and how long
Data processing agreementlegal.dpa, or the one governance generatesYour role per class, the sub-processors and the window for a person's request
Imprintlegal.imprintThe seller's name, address and contact
The refund ruleThe OfferThe rule each receipt cites

Your text places a fact by name, such as the processor list, so a deploy that adds a processor updates the page that lists it. A Live product that charges and has no terms or privacy text is refused at publish with legal_missing.

Versions and acceptance

Each page has a digest per version, and every old version stays at its own address.

A Customer accepts the terms digest at sign-up; an agent sends it in Accept-Terms, and each receipt names it. A change reaches Customers by the notice rule on agreements and price changes.

Text of your own, one tag

The weekly brief supplies its own terms and privacy notice, and adds one advertising tag behind consent.

definition.ts
33 lines
import { define, generative } from 'apis.dev'

/** A weekly brief on the software companies that changed headcount, for members and their agents. */
export default define({
  name: 'briefs', domain: 'briefs.apis.dev',
  sources: {
    firms: { api: 'companyfacts.apis.dev', cost: { 'Company.search': 0.005 } },
  },
  Issue: {
    week: 'string!#', title: 'string', body: 'markdown',
    status: {
      draft:   { run: generative('This week in {firms}: who hired, who shrank') },
      review:  { in: 'drafted', role: 'editor' },
      publish: { in: 'reviewed', role: 'editor' },
      send:    { in: 'published', to: 'Member' },
    },
  },
  on: { 'every Mon 06:00': 'Issue.draft', 'Issue.published': 'Issue.send' },
  offer: {
    'Issue.list': 0, 'Issue.read': 0.25,
    Member: { month: 8, includes: { 'Issue.read': 'all' } },
  },
  legal: {
    entity:  'Briefs Media LLC',
    terms:   './legal/terms.md',                // your words
    privacy: './legal/privacy.md',
    contact: 'legal@briefs.apis.dev',
  },
  consent: {
    tags: { ads: { src: 'https://tags.example.com/t.js', category: 'ads' } },
    gpc: true,                                  // the privacy signal refuses
  },
})

A visitor who refused advertising leaves this record behind.

Consent record
8 lines
{
  "type": "Consent.recorded",
  "at": "2026-10-28T14:20:05Z",
  "visitor": "vis_8c2e",
  "notice": "sha256:41d0e9a2",
  "choices": { "analytics": true, "ads": false, "support": true },
  "by": "prompt"
}