FreePrivacyPolicy

Rechtliche Seiten in Ihre App integrieren

Eine Anfrage erstellt Ihre Datenschutzerklärung, Nutzungsbedingungen, EULA und Standards zum Kinderschutz und hostet sie mit Unternehmensseite und app-ads.txt unter {slug}.freeprivacypolicy.app. Kostenlos, ohne Limit bei Richtlinien.

Endpunkte
16
Rate-Limit
60/min
Spezifikation
OpenAPI 3.1

POST /api/v1/policies

{
    "name": "Pocket Notes",
    "product_type": "mobile_app",
    "country": "Portugal",
    "services": [
        "admob",
        "firebase_analytics"
    ]
}

201 Created, sofort online

  • pocket-notes.freeprivacypolicy.app/ (Unternehmensseite)
  • pocket-notes.freeprivacypolicy.app/privacy-policy (Datenschutzerklärung)
  • pocket-notes.freeprivacypolicy.app/terms-of-service (Nutzungsbedingungen)
  • pocket-notes.freeprivacypolicy.app/end-user-license-agreement (EULA)
  • pocket-notes.freeprivacypolicy.app/child-safety-standards (Standards zum Kinderschutz)
  • pocket-notes.freeprivacypolicy.app/ads.txt (ads.txt)
  • pocket-notes.freeprivacypolicy.app/app-ads.txt (app-ads.txt)
Auf dieser Seite

Schnellstart

In drei Schritten zu einer Datenschutzerklärung-URL, die Sie in App Store Connect oder Google Play einfügen können.

  1. Kostenloses Konto erstellen

    Richtlinien, Unternehmen und Schlüssel gehören zu Ihrem Konto. Kein Tarif zu wählen, keine Karte zu hinterlegen.

  2. Persönlichen Schlüssel erstellen

    Öffnen Sie die Assistenten-Seite und wählen Sie Meinen Schlüssel erstellen. Er wird nur einmal angezeigt, speichern Sie ihn also sofort, zum Beispiel als FPP_API_KEY in Ihren CI-Secrets oder Ihrer Shell.

    Shell
    export FPP_API_KEY="fpp_your_key_here"
  3. Erste Richtlinie veröffentlichen

    Senden Sie Name, Produkttyp und Ihr Land. Fügen Sie die Dienste Ihrer App hinzu, damit die Richtlinie sie offenlegt.

    Anfrage
    curl -X POST "https://freeprivacypolicy.app/api/v1/policies" \
      -H "Authorization: Bearer $FPP_API_KEY" \
      -H "Accept: application/json" \
      -H "Content-Type: application/json" \
      -d '{"name": "Pocket Notes", "product_type": "mobile_app", "country": "Portugal", "services": ["admob", "firebase_analytics"]}'

    Die Antwort enthält alle Adressen, bereits online:

    201-Antwort
    {
        "data": {
            "slug": "pocket-notes",
            "name": "Pocket Notes",
            "published": true,
            "public_urls": {
                "landing": "https://pocket-notes.freeprivacypolicy.app",
                "privacy_policy": "https://pocket-notes.freeprivacypolicy.app/privacy-policy",
                "terms": "https://pocket-notes.freeprivacypolicy.app/terms-of-service",
                "eula": "https://pocket-notes.freeprivacypolicy.app/end-user-license-agreement",
                "child_safety": "https://pocket-notes.freeprivacypolicy.app/child-safety-standards",
                "ads_txt": "https://pocket-notes.freeprivacypolicy.app/ads.txt",
                "app_ads_txt": "https://pocket-notes.freeprivacypolicy.app/app-ads.txt"
            }
        }
    }

Authentifizierung

Jede Anfrage enthält Ihren persönlichen Schlüssel in einem der beiden Header. Anfragen ohne gültigen Schlüssel erhalten 401.

  • Ein Schlüssel, zwei Einsatzzwecke. Derselbe Schlüssel verbindet Claude Code und Codex über MCP und ruft die REST API auf.
  • Ein neuer Schlüssel ersetzt den alten. Ein neuer Schlüssel trennt den vorherigen Schlüssel sofort überall.
  • Nur Ihr Konto. Ein Schlüssel liest und ändert nur Ihre eigenen Richtlinien und Unternehmen. Datensätze anderer Konten liefern 404.
  • Bewahren Sie ihn auf dem Server auf. Liefern Sie den Schlüssel nie in einer App-Binärdatei oder Webseite aus. Rufen Sie die API aus CI, einem Backend oder von Ihrem Rechner auf.
  • 60 Anfragen pro Minute pro Schlüssel. Jede Antwort enthält X-RateLimit-Remaining.
curl "https://freeprivacypolicy.app/api/v1/me" \
  -H "Authorization: Bearer $FPP_API_KEY" \
  -H "Accept: application/json"

Integrationsrezepte

Sofort nutzbare Abläufe für die Aufgaben, die Entwickler am häufigsten automatisieren. Wählen Sie einmal eine Sprache, und alle Beispiele auf der Seite folgen.

Publish the policy when you ship

Run this in your release pipeline. It creates the policy the first time and updates it on every release after that, so the hosted text always matches the SDKs in the build you ship.

  • Store the key as a secret named FPP_API_KEY. Never commit it.
  • If the slug you ask for is taken, the API adds a suffix (pocket-notes-2). Keep the slug it returns.
  • A PATCH that changes settings writes the text again. Text you edited by hand in the dashboard is replaced only when you send markdown.
# .github/workflows/privacy-policy.yml
name: Privacy policy

on:
  push:
    tags: ["v*"]

jobs:
  publish:
    runs-on: ubuntu-latest
    steps:
      - name: Create or update the hosted policy
        env:
          FPP_API_KEY: ${{ secrets.FPP_API_KEY }}
          API: https://freeprivacypolicy.app/api/v1
          SLUG: pocket-notes
        run: |
          SETTINGS='{"name":"Pocket Notes","product_type":"mobile_app","country":"Portugal","services":["admob","firebase_analytics","revenuecat"]}'
          AUTH=(-H "Authorization: Bearer $FPP_API_KEY" -H "Accept: application/json" -H "Content-Type: application/json")

          STATUS=$(curl -s -o /dev/null -w "%{http_code}" "${AUTH[@]}" "$API/policies/$SLUG")

          if [ "$STATUS" = "404" ]; then
            curl -fsS -X POST "$API/policies" "${AUTH[@]}" \
              -d "$(echo "$SETTINGS" | jq --arg slug "$SLUG" '. + {slug: $slug}')"
          else
            curl -fsS -X PATCH "$API/policies/$SLUG" "${AUTH[@]}" -d "$SETTINGS"
          fi

Fill in App Store Connect and Google Play

Every policy response carries public_urls. Paste them into the store fields below once; the addresses never change, even when you update the text.

App Store Connect: Privacy Policy URL
privacy_policy
App Store Connect: License Agreement (custom EULA)
eula
Google Play Console: Privacy policy
privacy_policy
Google Play Console: Child safety standards
child_safety
Store listing: Website (used by ad networks for app-ads.txt)
landing
Terms link inside your app or website
terms
curl -s "https://freeprivacypolicy.app/api/v1/policies/pocket-notes" \
  -H "Authorization: Bearer $FPP_API_KEY" \
  -H "Accept: application/json" \
  | jq '.data.public_urls'

Keep app-ads.txt in sync for ad networks

AdMob, AppLovin, Unity and other networks read app-ads.txt from the website on your store listing. Set that website to the policy address (public_urls.landing) and keep the lines on your company: every policy subdomain serves the lines of all your companies, merged and without duplicates.

  • Send the whole file: app_ads_txt replaces the previous lines.
  • Changes are live at https://{slug}.freeprivacypolicy.app/app-ads.txt right away. Ad networks re-crawl on their own schedule, usually within 24 hours.
  • ads_txt works the same way for websites and is served per company.
curl -X PATCH "https://freeprivacypolicy.app/api/v1/companies/42" \
  -H "Authorization: Bearer $FPP_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "app_ads_txt": "google.com, pub-1234567890123456, DIRECT, f08c47fec0942fa0\napplovin.com, 0123456789abcdef, DIRECT"
  }'

# Check what ad networks will read
curl -s https://pocket-notes.freeprivacypolicy.app/app-ads.txt

Update the policy when you add an SDK

Each service adds its own disclosure. services replaces the whole list, so read the current one, add the new key and send it back. Valid keys come from GET /options.

SERVICES=$(curl -s "https://freeprivacypolicy.app/api/v1/policies/pocket-notes" \
  -H "Authorization: Bearer $FPP_API_KEY" -H "Accept: application/json" \
  | jq -c '.data.services + ["openai"] | unique')

curl -X PATCH "https://freeprivacypolicy.app/api/v1/policies/pocket-notes" \
  -H "Authorization: Bearer $FPP_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d "{\"services\": $SERVICES, \"clauses\": [\"accounts\", \"ai\"]}"

Share one company across several apps

A company holds the publisher details shown on every page, plus ads.txt and app-ads.txt. Create it once, then pass its id as company_id to each new policy. Upload a logo in the dashboard; the API does not accept files.

# 1. Create the company
curl -X POST "https://freeprivacypolicy.app/api/v1/companies" \
  -H "Authorization: Bearer $FPP_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"company_name": "Acme Labs Ltd.", "email": "[email protected]", "address": "1 Market Street, Lisbon"}'

# 2. Publish each app with its id
curl -X POST "https://freeprivacypolicy.app/api/v1/policies" \
  -H "Authorization: Bearer $FPP_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{"name": "Pocket Notes", "product_type": "mobile_app", "country": "Portugal", "company_id": 42}'

# 3. List everything in the account
curl -s "https://freeprivacypolicy.app/api/v1/companies?per_page=100" -H "Authorization: Bearer $FPP_API_KEY" -H "Accept: application/json"

MCP-Server unter https://freeprivacypolicy.app/mcp

Lieber Ihren KI-Assistenten fragen?

Derselbe Schlüssel verbindet Claude Code, Claude Desktop, Codex, Cursor und VS Code. Der Assistent liest Ihre Abhängigkeiten, wählt die Dienste aus, die Ihre App wirklich nutzt, und ruft diese Endpunkte für Sie auf: veröffentlichen, aktualisieren, Unternehmen, app-ads.txt.

Claude Code von Anthropic

Im Terminal ausführen
claude mcp add --transport http --scope user freeprivacypolicy https://freeprivacypolicy.app/mcp --header "Authorization: Bearer YOUR_KEY"

Claude Desktop von Anthropic

claude_desktop_config.json
{
    "mcpServers": {
        "freeprivacypolicy": {
            "command": "npx",
            "args": [
                "-y",
                "mcp-remote",
                "https://freeprivacypolicy.app/mcp",
                "--header",
                "Authorization:${AUTH_HEADER}",
                "--transport",
                "http-only"
            ],
            "env": {
                "AUTH_HEADER": "Bearer YOUR_KEY"
            }
        }
    }
}

Codex von OpenAI

~/.codex/config.toml
[mcp_servers.freeprivacypolicy]
url = "https://freeprivacypolicy.app/mcp"
http_headers = { "Authorization" = "Bearer YOUR_KEY" }

Cursor von Anysphere

~/.cursor/mcp.json
{
    "mcpServers": {
        "freeprivacypolicy": {
            "url": "https://freeprivacypolicy.app/mcp",
            "headers": {
                "Authorization": "Bearer YOUR_KEY"
            }
        }
    }
}

Cursor kann es auch über einen Link installieren: anmelden und Cursor verbinden, um Ihren Link mit bereits eingetragenem Schlüssel zu erhalten.

VS Code von Microsoft · GitHub Copilot Agent-Modus

Im Terminal ausführen
code --add-mcp '{"name":"freeprivacypolicy","type":"http","url":"https://freeprivacypolicy.app/mcp","headers":{"Authorization":"Bearer YOUR_KEY"}}'

VS Code kann es auch über einen Link installieren: anmelden und VS Code verbinden, um Ihren Link mit bereits eingetragenem Schlüssel zu erhalten.

Assistenten verbinden

API-Referenz

Generiert aus dem OpenAPI-Dokument, Version 1.0.0.

Basis-URL https://freeprivacypolicy.app/api/v1

Account

The account the API key belongs to.

Get the current account

GET /me

Returns the account the API key belongs to, with how many policies and companies it has. Handy to check that a key works.

Antworten
  • 200

    The account.

  • 401

    The key is missing, invalid, revoked or its account is suspended.

  • 429

    More than 60 requests in a minute with this key.

curl -X GET "https://freeprivacypolicy.app/api/v1/me" \
  -H "Authorization: Bearer $FPP_API_KEY" \
  -H "Accept: application/json"
200-Antwort
{
    "data": {
        "id": 7,
        "name": "Ada Lovelace",
        "email": "[email protected]",
        "policies_count": 2,
        "companies_count": 1
    }
}

Catalog

Product types, third-party services, optional sections and countries a policy can use.

List policy options

GET /options

Everything a policy can cover: product types, third-party services (each adds its own disclosure), optional sections, document languages and countries. Use the key values in product_type, services and clauses, a country name in country and a language code in language.

Antworten
  • 200

    The catalog.

  • 401

    The key is missing, invalid, revoked or its account is suspended.

  • 429

    More than 60 requests in a minute with this key.

curl -X GET "https://freeprivacypolicy.app/api/v1/options" \
  -H "Authorization: Bearer $FPP_API_KEY" \
  -H "Accept: application/json"
200-Antwort
{
    "data": {
        "product_types": [
            {
                "key": "mobile_app",
                "label": "Mobile App"
            }
        ],
        "services": [
            {
                "key": "admob",
                "label": "AdMob",
                "group": "Ads",
                "description": "We use Google AdMob to serve personalized and non-personalized ads in our product...",
                "products": [
                    "mobile_app",
                    "game"
                ],
                "ads": true
            }
        ],
        "clauses": [
            {
                "key": "accounts",
                "label": "Accounts and sign-in",
                "category": "Data you collect",
                "description": "Explain the details collected when people create an account."
            }
        ],
        "languages": [
            {
                "code": "en",
                "name": "English"
            },
            {
                "code": "pt_BR",
                "name": "Português (Brasil)"
            }
        ],
        "countries": [
            {
                "code": "PT",
                "name": "Portugal"
            }
        ]
    }
}

Policies

Generate, publish, update and take down the legal pages hosted on {slug}.freeprivacypolicy.app.

List policies

GET /policies

Your policies, published or not, sorted by name.

Parameter
  • page integer in query

    Page number, starting at 1. Standard: 1.

  • per_page integer in query

    Items per page, 1 to 100. Standard: 25.

Antworten
  • 200

    A page of policies.

  • 401

    The key is missing, invalid, revoked or its account is suspended.

  • 422

    The request is invalid. errors lists the messages per field.

  • 429

    More than 60 requests in a minute with this key.

curl -X GET "https://freeprivacypolicy.app/api/v1/policies?per_page=25" \
  -H "Authorization: Bearer $FPP_API_KEY" \
  -H "Accept: application/json"
200-Antwort
{
    "data": [
        {
            "id": 1287,
            "slug": "pocket-notes",
            "name": "Pocket Notes",
            "product_type": "mobile_app",
            "country": "Portugal",
            "services": [
                "admob",
                "firebase_analytics",
                "revenuecat"
            ],
            "clauses": [
                "accounts",
                "metadata"
            ],
            "markdown": "# Privacy Policy\n\nThis Privacy Policy explains how Acme Labs Ltd. collects, uses and protects information when you use Pocket Notes...",
            "html": "<h1>Privacy Policy</h1>\n<p>This Privacy Policy explains how Acme Labs Ltd. collects, uses and protects information when you use Pocket Notes...</p>",
            "published": true,
            "published_at": "2026-09-20T08:30:00+00:00",
            "noindex": false,
            "company_id": 42,
            "contact": {
                "id": 42,
                "company_name": "Acme Labs Ltd.",
                "address": "1 Market Street, Lisbon, Portugal",
                "email": "[email protected]",
                "about": "Acme Labs builds productivity apps for small teams.",
                "ads_txt": "google.com, pub-1234567890123456, DIRECT, f08c47fec0942fa0",
                "app_ads_txt": "google.com, pub-1234567890123456, DIRECT, f08c47fec0942fa0",
                "show_resources_publicly": true
            },
            "public_urls": {
                "landing": "https://pocket-notes.freeprivacypolicy.app",
                "privacy_policy": "https://pocket-notes.freeprivacypolicy.app/privacy-policy",
                "child_safety": "https://pocket-notes.freeprivacypolicy.app/child-safety-standards",
                "eula": "https://pocket-notes.freeprivacypolicy.app/end-user-license-agreement",
                "terms": "https://pocket-notes.freeprivacypolicy.app/terms-of-service",
                "ads_txt": "https://pocket-notes.freeprivacypolicy.app/ads.txt",
                "app_ads_txt": "https://pocket-notes.freeprivacypolicy.app/app-ads.txt"
            },
            "created_at": "2026-09-20T08:30:00+00:00",
            "updated_at": "2026-09-20T08:30:00+00:00"
        }
    ],
    "links": {
        "first": "https://freeprivacypolicy.app/api/v1/policies?page=1",
        "last": "https://freeprivacypolicy.app/api/v1/policies?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "links": [
            {
                "url": null,
                "label": "&laquo; Previous",
                "page": null,
                "active": false
            },
            {
                "url": "https://freeprivacypolicy.app/api/v1/policies?page=1",
                "label": "1",
                "page": 1,
                "active": true
            },
            {
                "url": null,
                "label": "Next &raquo;",
                "page": null,
                "active": false
            }
        ],
        "path": "https://freeprivacypolicy.app/api/v1/policies",
        "per_page": 25,
        "to": 1,
        "total": 1
    }
}

Generate and publish a policy

POST /policies

Writes the policy from the settings you send and publishes it right away on {slug}.freeprivacypolicy.app.

The publisher shown on the pages comes from, in order:

  1. company_id: one of your companies (GET /companies), shared between policies;
  2. contact: a new company used only by this policy;
  3. nothing: a new company named after the policy, with {slug}@freeprivacypolicy.app as the email.

company_id and contact cannot be sent together.

Body PolicyInput
  • name string erforderlich

    Name of the app, game, website or company, as users know it.

  • product_type string erforderlich

    What the product is. See GET /options for labels.

    website mobile_app saas game desktop_app browser_extension

  • country string erforderlich

    Country you operate from, as an English name (see countries in GET /options).

  • language string

    Language the legal documents and public pages are written in (see languages in GET /options). Defaults to en.

    Standard: "en".

    en pt_BR es fr de it ja

  • services string[] | null

    Third-party services the product uses. Each one adds its own disclosure. Replaces the whole list on update.

    37 zulässige Werte

    admob facebook_audience_network facebook_pixel firebase_analytics firebase_crashlytics google_analytics google_sign_in sign_in_with_apple facebook_login firebase_cloud_messaging onesignal revenuecat stripe sentry mixpanel amplitude appsflyer unity_ads applovin google_maps openai qonversion adapty superwall adjust branch ironsource paddle auth0 clerk posthog segment hotjar intercom hubspot zendesk anthropic

  • clauses string[] | null

    Optional sections, such as accounts, location or gdpr. Replaces the whole list on update.

    30 zulässige Werte

    accounts metadata location contacts camera_media microphone biometrics health purchases financial identity_verification credit_partners notifications marketing ugc ai advertising analytics no_sale retention account_deletion international_transfers third_party_links children gdpr ccpa lgpd us_states canada mexico

  • slug string | null

    Subdomain of the public pages ({slug}.freeprivacypolicy.app). Lowercase letters, numbers and hyphens; defaults to the name. When taken, a numeric suffix is added (pocket-notes-2); reserved words (www, api, docs, ...) are rejected with 422.

  • markdown string | null

    Your own policy text in Markdown. When sent, it is published as given instead of the generated text.

  • noindex boolean | null

    true asks search engines not to index the public pages (they stay online).

    Standard: false.

  • company_id integer | null

    Id of one of your companies (GET /companies). Its contact details, logo and ads.txt are used. Cannot be combined with contact.

  • contact object

    Publisher details for a company used only by this policy.

  • contact.company_name string

    Legal or trading name shown as the publisher. Defaults to the policy name.

  • contact.email string

    Where users reach you about privacy. When left out on create, {slug}@freeprivacypolicy.app is used.

  • contact.address string | null

    Postal address, only when you want it published.

  • contact.about string | null

    Short description shown on the company page.

  • contact.ads_txt string | null

    Full ads.txt content for websites, one seller line per row.

  • contact.app_ads_txt string | null

    Full app-ads.txt content for mobile apps, one seller line per row.

  • contact.show_resources_publicly boolean

    List the ads.txt and app-ads.txt links on the company page.

    Standard: false.

  • accent_color string | null

    Accent color of the public pages as #RRGGBB, or null for the default. Links and buttons use it; text shades are darkened automatically to keep AA contrast.

  • theme string

    Look of the public pages: classic (default), minimal (plain document) or card (document on a raised card under a band in the accent color).

    Standard: "classic".

    classic minimal card

Antworten
  • 201

    The policy was published.

  • 401

    The key is missing, invalid, revoked or its account is suspended.

  • 422

    The request is invalid. errors lists the messages per field.

  • 429

    More than 60 requests in a minute with this key.

curl -X POST "https://freeprivacypolicy.app/api/v1/policies" \
  -H "Authorization: Bearer $FPP_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Pocket Notes",
    "product_type": "mobile_app",
    "country": "Portugal",
    "services": [
        "admob",
        "firebase_analytics",
        "revenuecat"
    ],
    "clauses": [
        "accounts",
        "metadata"
    ],
    "slug": "pocket-notes",
    "contact": {
        "company_name": "Acme Labs Ltd.",
        "email": "[email protected]",
        "address": "1 Market Street, Lisbon, Portugal",
        "app_ads_txt": "google.com, pub-1234567890123456, DIRECT, f08c47fec0942fa0",
        "show_resources_publicly": true
    }
}'
Request-Body: Only the required fields
{
    "name": "Pocket Notes",
    "product_type": "mobile_app",
    "country": "Portugal"
}
201-Antwort
{
    "data": {
        "id": 1287,
        "slug": "pocket-notes",
        "name": "Pocket Notes",
        "product_type": "mobile_app",
        "country": "Portugal",
        "language": "en",
        "services": [
            "admob",
            "firebase_analytics",
            "revenuecat"
        ],
        "clauses": [
            "accounts",
            "metadata"
        ],
        "markdown": "# Privacy Policy\n\nThis Privacy Policy explains how Acme Labs Ltd. collects, uses and protects information when you use Pocket Notes...",
        "html": "<h1>Privacy Policy</h1>\n<p>This Privacy Policy explains how Acme Labs Ltd. collects, uses and protects information when you use Pocket Notes...</p>",
        "published": true,
        "published_at": "2026-09-20T08:30:00+00:00",
        "noindex": false,
        "app_icon_url": null,
        "logo_url": null,
        "accent_color": null,
        "theme": "classic",
        "company_id": 42,
        "contact": {
            "id": 42,
            "company_name": "Acme Labs Ltd.",
            "address": "1 Market Street, Lisbon, Portugal",
            "email": "[email protected]",
            "about": "Acme Labs builds productivity apps for small teams.",
            "ads_txt": "google.com, pub-1234567890123456, DIRECT, f08c47fec0942fa0",
            "app_ads_txt": "google.com, pub-1234567890123456, DIRECT, f08c47fec0942fa0",
            "show_resources_publicly": true
        },
        "public_urls": {
            "landing": "https://pocket-notes.freeprivacypolicy.app",
            "privacy_policy": "https://pocket-notes.freeprivacypolicy.app/privacy-policy",
            "child_safety": "https://pocket-notes.freeprivacypolicy.app/child-safety-standards",
            "eula": "https://pocket-notes.freeprivacypolicy.app/end-user-license-agreement",
            "terms": "https://pocket-notes.freeprivacypolicy.app/terms-of-service",
            "ads_txt": "https://pocket-notes.freeprivacypolicy.app/ads.txt",
            "app_ads_txt": "https://pocket-notes.freeprivacypolicy.app/app-ads.txt"
        },
        "created_at": "2026-09-20T08:30:00+00:00",
        "updated_at": "2026-09-20T08:30:00+00:00"
    }
}

Get a policy

GET /policies/{slug}

One of your policies, with its Markdown and HTML text and the addresses of its public pages.

Parameter
  • slug string in path erforderlich

    The policy slug (its subdomain).

Antworten
  • 200

    The policy.

  • 401

    The key is missing, invalid, revoked or its account is suspended.

  • 404

    No such record in this account.

  • 429

    More than 60 requests in a minute with this key.

curl -X GET "https://freeprivacypolicy.app/api/v1/policies/pocket-notes" \
  -H "Authorization: Bearer $FPP_API_KEY" \
  -H "Accept: application/json"
200-Antwort
{
    "data": {
        "id": 1287,
        "slug": "pocket-notes",
        "name": "Pocket Notes",
        "product_type": "mobile_app",
        "country": "Portugal",
        "language": "en",
        "services": [
            "admob",
            "firebase_analytics",
            "revenuecat"
        ],
        "clauses": [
            "accounts",
            "metadata"
        ],
        "markdown": "# Privacy Policy\n\nThis Privacy Policy explains how Acme Labs Ltd. collects, uses and protects information when you use Pocket Notes...",
        "html": "<h1>Privacy Policy</h1>\n<p>This Privacy Policy explains how Acme Labs Ltd. collects, uses and protects information when you use Pocket Notes...</p>",
        "published": true,
        "published_at": "2026-09-20T08:30:00+00:00",
        "noindex": false,
        "app_icon_url": null,
        "logo_url": null,
        "accent_color": null,
        "theme": "classic",
        "company_id": 42,
        "contact": {
            "id": 42,
            "company_name": "Acme Labs Ltd.",
            "address": "1 Market Street, Lisbon, Portugal",
            "email": "[email protected]",
            "about": "Acme Labs builds productivity apps for small teams.",
            "ads_txt": "google.com, pub-1234567890123456, DIRECT, f08c47fec0942fa0",
            "app_ads_txt": "google.com, pub-1234567890123456, DIRECT, f08c47fec0942fa0",
            "show_resources_publicly": true
        },
        "public_urls": {
            "landing": "https://pocket-notes.freeprivacypolicy.app",
            "privacy_policy": "https://pocket-notes.freeprivacypolicy.app/privacy-policy",
            "child_safety": "https://pocket-notes.freeprivacypolicy.app/child-safety-standards",
            "eula": "https://pocket-notes.freeprivacypolicy.app/end-user-license-agreement",
            "terms": "https://pocket-notes.freeprivacypolicy.app/terms-of-service",
            "ads_txt": "https://pocket-notes.freeprivacypolicy.app/ads.txt",
            "app_ads_txt": "https://pocket-notes.freeprivacypolicy.app/app-ads.txt"
        },
        "created_at": "2026-09-20T08:30:00+00:00",
        "updated_at": "2026-09-20T08:30:00+00:00"
    }
}

Update a policy

PATCH /policies/{slug}

Only the fields you send change.

  • Settings (name, product_type, country, language, services, clauses, contact, company_id) regenerate the text, which replaces edits made by hand. Send markdown in the same request to keep your own text.
  • markdown alone replaces the text as given.
  • published: false takes every public page offline (404); true puts them back.
  • noindex and slug never touch the text.
  • company_id: null detaches the company; the pages then use the contact details saved with the policy.
Parameter
  • slug string in path erforderlich

    The policy slug (its subdomain).

Body PolicyUpdate
  • name string

    Name of the app, game, website or company, as users know it.

  • product_type string

    What the product is. See GET /options for labels.

    website mobile_app saas game desktop_app browser_extension

  • country string

    Country you operate from, as an English name (see countries in GET /options).

  • language string

    Language the legal documents and public pages are written in. Changing it regenerates the text, like the other settings.

    en pt_BR es fr de it ja

  • services string[] | null

    Third-party services the product uses. Each one adds its own disclosure. Replaces the whole list on update.

    37 zulässige Werte

    admob facebook_audience_network facebook_pixel firebase_analytics firebase_crashlytics google_analytics google_sign_in sign_in_with_apple facebook_login firebase_cloud_messaging onesignal revenuecat stripe sentry mixpanel amplitude appsflyer unity_ads applovin google_maps openai qonversion adapty superwall adjust branch ironsource paddle auth0 clerk posthog segment hotjar intercom hubspot zendesk anthropic

  • clauses string[] | null

    Optional sections, such as accounts, location or gdpr. Replaces the whole list on update.

    30 zulässige Werte

    accounts metadata location contacts camera_media microphone biometrics health purchases financial identity_verification credit_partners notifications marketing ugc ai advertising analytics no_sale retention account_deletion international_transfers third_party_links children gdpr ccpa lgpd us_states canada mexico

  • slug string | null

    Subdomain of the public pages ({slug}.freeprivacypolicy.app). Lowercase letters, numbers and hyphens; defaults to the name. When taken, a numeric suffix is added (pocket-notes-2); reserved words (www, api, docs, ...) are rejected with 422.

  • markdown string | null

    Your own policy text in Markdown. When sent, it is published as given instead of the generated text.

  • company_id integer | null

    Id of one of your companies, or null to detach the current one. Cannot be combined with contact.

  • contact object

    Publisher details for a company used only by this policy.

  • contact.company_name string

    Legal or trading name shown as the publisher. Defaults to the policy name.

  • contact.email string

    Where users reach you about privacy. When left out on create, {slug}@freeprivacypolicy.app is used.

  • contact.address string | null

    Postal address, only when you want it published.

  • contact.about string | null

    Short description shown on the company page.

  • contact.ads_txt string | null

    Full ads.txt content for websites, one seller line per row.

  • contact.app_ads_txt string | null

    Full app-ads.txt content for mobile apps, one seller line per row.

  • contact.show_resources_publicly boolean

    List the ads.txt and app-ads.txt links on the company page.

    Standard: false.

  • noindex boolean

    true asks search engines not to index the public pages (they stay online).

  • published boolean

    false takes every public page offline (404); true publishes them again.

  • accent_color string | null

    Accent color of the public pages as #RRGGBB, or null for the default. Links and buttons use it; text shades are darkened automatically to keep AA contrast.

  • theme string

    Look of the public pages: classic (default), minimal (plain document) or card (document on a raised card under a band in the accent color).

    Standard: "classic".

    classic minimal card

Antworten
  • 200

    The updated policy.

  • 401

    The key is missing, invalid, revoked or its account is suspended.

  • 404

    No such record in this account.

  • 422

    The request is invalid. errors lists the messages per field.

  • 429

    More than 60 requests in a minute with this key.

curl -X PATCH "https://freeprivacypolicy.app/api/v1/policies/pocket-notes" \
  -H "Authorization: Bearer $FPP_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "services": [
        "admob",
        "firebase_analytics",
        "revenuecat",
        "openai"
    ],
    "clauses": [
        "accounts",
        "metadata",
        "ai"
    ]
}'
Request-Body: Add a service and a section
{
    "services": [
        "admob",
        "firebase_analytics",
        "revenuecat",
        "openai"
    ],
    "clauses": [
        "accounts",
        "metadata",
        "ai"
    ]
}
200-Antwort
{
    "data": {
        "id": 1287,
        "slug": "pocket-notes",
        "name": "Pocket Notes",
        "product_type": "mobile_app",
        "country": "Portugal",
        "language": "en",
        "services": [
            "admob",
            "firebase_analytics",
            "revenuecat"
        ],
        "clauses": [
            "accounts",
            "metadata"
        ],
        "markdown": "# Privacy Policy\n\nThis Privacy Policy explains how Acme Labs Ltd. collects, uses and protects information when you use Pocket Notes...",
        "html": "<h1>Privacy Policy</h1>\n<p>This Privacy Policy explains how Acme Labs Ltd. collects, uses and protects information when you use Pocket Notes...</p>",
        "published": true,
        "published_at": "2026-09-20T08:30:00+00:00",
        "noindex": false,
        "app_icon_url": null,
        "logo_url": null,
        "accent_color": null,
        "theme": "classic",
        "company_id": 42,
        "contact": {
            "id": 42,
            "company_name": "Acme Labs Ltd.",
            "address": "1 Market Street, Lisbon, Portugal",
            "email": "[email protected]",
            "about": "Acme Labs builds productivity apps for small teams.",
            "ads_txt": "google.com, pub-1234567890123456, DIRECT, f08c47fec0942fa0",
            "app_ads_txt": "google.com, pub-1234567890123456, DIRECT, f08c47fec0942fa0",
            "show_resources_publicly": true
        },
        "public_urls": {
            "landing": "https://pocket-notes.freeprivacypolicy.app",
            "privacy_policy": "https://pocket-notes.freeprivacypolicy.app/privacy-policy",
            "child_safety": "https://pocket-notes.freeprivacypolicy.app/child-safety-standards",
            "eula": "https://pocket-notes.freeprivacypolicy.app/end-user-license-agreement",
            "terms": "https://pocket-notes.freeprivacypolicy.app/terms-of-service",
            "ads_txt": "https://pocket-notes.freeprivacypolicy.app/ads.txt",
            "app_ads_txt": "https://pocket-notes.freeprivacypolicy.app/app-ads.txt"
        },
        "created_at": "2026-09-20T08:30:00+00:00",
        "updated_at": "2026-09-20T08:30:00+00:00"
    }
}

Delete a policy

DELETE /policies/{slug}

Deletes the policy for good. Its public pages answer 404 and the slug becomes free. Its company is kept. To only take the pages offline, send published: false instead.

Parameter
  • slug string in path erforderlich

    The policy slug (its subdomain).

Antworten
  • 204

    Deleted.

  • 401

    The key is missing, invalid, revoked or its account is suspended.

  • 404

    No such record in this account.

  • 429

    More than 60 requests in a minute with this key.

curl -X DELETE "https://freeprivacypolicy.app/api/v1/policies/pocket-notes" \
  -H "Authorization: Bearer $FPP_API_KEY" \
  -H "Accept: application/json"

204 hat keinen Body.

Upload the app icon

POST /policies/{slug}/app-icon

Sends the app icon as multipart/form-data. It must be a square PNG, JPG or WebP of at least 128 × 128 px and up to 1 MB. The public pages show it next to the name and use it as favicon, touch icon and share image. Replaces the current icon.

Parameter
  • slug string in path erforderlich

    The policy slug (its subdomain).

Body
  • app_icon string erforderlich

    Square PNG, JPG or WebP, at least 128 × 128 px, up to 1 MB.

Antworten
  • 200

    The policy with its new app_icon_url.

  • 401

    The key is missing, invalid, revoked or its account is suspended.

  • 404

    No such record in this account.

  • 429

    More than 60 requests in a minute with this key.

  • 422

    The request is invalid. errors lists the messages per field.

curl -X POST "https://freeprivacypolicy.app/api/v1/policies/pocket-notes/app-icon" \
  -H "Authorization: Bearer $FPP_API_KEY" \
  -H "Accept: application/json" \
  -F "[email protected]"

200 hat keinen Body.

Remove the app icon

DELETE /policies/{slug}/app-icon

Deletes the app icon. The pages fall back to the company logo, or to the initial of the name.

Parameter
  • slug string in path erforderlich

    The policy slug (its subdomain).

Antworten
  • 200

    The policy, with app_icon_url null.

  • 401

    The key is missing, invalid, revoked or its account is suspended.

  • 404

    No such record in this account.

  • 429

    More than 60 requests in a minute with this key.

curl -X DELETE "https://freeprivacypolicy.app/api/v1/policies/pocket-notes/app-icon" \
  -H "Authorization: Bearer $FPP_API_KEY" \
  -H "Accept: application/json"

200 hat keinen Body.

Companies

Publisher details shown on the policy pages, their logo, plus the ads.txt and app-ads.txt lines they serve.

List companies

GET /companies

Your companies, sorted by name, with how many policies use each one.

Parameter
  • page integer in query

    Page number, starting at 1. Standard: 1.

  • per_page integer in query

    Items per page, 1 to 100. Standard: 25.

Antworten
  • 200

    A page of companies.

  • 401

    The key is missing, invalid, revoked or its account is suspended.

  • 422

    The request is invalid. errors lists the messages per field.

  • 429

    More than 60 requests in a minute with this key.

curl -X GET "https://freeprivacypolicy.app/api/v1/companies?per_page=25" \
  -H "Authorization: Bearer $FPP_API_KEY" \
  -H "Accept: application/json"
200-Antwort
{
    "data": [
        {
            "id": 42,
            "company_name": "Acme Labs Ltd.",
            "email": "[email protected]",
            "address": "1 Market Street, Lisbon, Portugal",
            "about": "Acme Labs builds productivity apps for small teams.",
            "ads_txt": "google.com, pub-1234567890123456, DIRECT, f08c47fec0942fa0",
            "app_ads_txt": "google.com, pub-1234567890123456, DIRECT, f08c47fec0942fa0",
            "show_resources_publicly": true,
            "logo_url": null,
            "policies_count": 2,
            "created_at": "2026-09-01T12:00:00+00:00",
            "updated_at": "2026-09-20T08:30:00+00:00"
        }
    ],
    "links": {
        "first": "https://freeprivacypolicy.app/api/v1/companies?page=1",
        "last": "https://freeprivacypolicy.app/api/v1/companies?page=1",
        "prev": null,
        "next": null
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 1,
        "links": [
            {
                "url": null,
                "label": "&laquo; Previous",
                "page": null,
                "active": false
            },
            {
                "url": "https://freeprivacypolicy.app/api/v1/companies?page=1",
                "label": "1",
                "page": 1,
                "active": true
            },
            {
                "url": null,
                "label": "Next &raquo;",
                "page": null,
                "active": false
            }
        ],
        "path": "https://freeprivacypolicy.app/api/v1/companies",
        "per_page": 25,
        "to": 1,
        "total": 1
    }
}

Create a company

POST /companies

Creates a publisher you can attach to policies with company_id.

ads_txt is served at {slug}/ads.txt for the policies using this company. app_ads_txt lines of all your companies are merged, de-duplicated and served at {slug}/app-ads.txt on every one of your policies.

Logos are uploaded in the dashboard; the API returns logo_url but does not accept files.

Body CompanyInput
  • company_name string erforderlich

  • email string erforderlich

  • address string | null

  • about string | null

  • ads_txt string | null

    Full ads.txt content, one seller line per row.

  • app_ads_txt string | null

    Full app-ads.txt content, one seller line per row.

  • show_resources_publicly boolean

    List the ads.txt and app-ads.txt links on the company page.

    Standard: false.

Antworten
  • 201

    The company was created.

  • 401

    The key is missing, invalid, revoked or its account is suspended.

  • 422

    The request is invalid. errors lists the messages per field.

  • 429

    More than 60 requests in a minute with this key.

curl -X POST "https://freeprivacypolicy.app/api/v1/companies" \
  -H "Authorization: Bearer $FPP_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "company_name": "Acme Labs Ltd.",
    "email": "[email protected]",
    "address": "1 Market Street, Lisbon, Portugal",
    "about": "Acme Labs builds productivity apps for small teams.",
    "app_ads_txt": "google.com, pub-1234567890123456, DIRECT, f08c47fec0942fa0\nunity.com, 1234567, DIRECT, 96cabb5fbdde37a7",
    "show_resources_publicly": true
}'
Request-Body: Company with app-ads.txt lines
{
    "company_name": "Acme Labs Ltd.",
    "email": "[email protected]",
    "address": "1 Market Street, Lisbon, Portugal",
    "about": "Acme Labs builds productivity apps for small teams.",
    "app_ads_txt": "google.com, pub-1234567890123456, DIRECT, f08c47fec0942fa0\nunity.com, 1234567, DIRECT, 96cabb5fbdde37a7",
    "show_resources_publicly": true
}
201-Antwort
{
    "data": {
        "id": 42,
        "company_name": "Acme Labs Ltd.",
        "email": "[email protected]",
        "address": "1 Market Street, Lisbon, Portugal",
        "about": "Acme Labs builds productivity apps for small teams.",
        "ads_txt": "google.com, pub-1234567890123456, DIRECT, f08c47fec0942fa0",
        "app_ads_txt": "google.com, pub-1234567890123456, DIRECT, f08c47fec0942fa0",
        "show_resources_publicly": true,
        "logo_url": null,
        "policies_count": 0,
        "created_at": "2026-09-01T12:00:00+00:00",
        "updated_at": "2026-09-20T08:30:00+00:00"
    }
}

Get a company

GET /companies/{id}

One of your companies.

Parameter
  • id integer in path erforderlich

    The company id.

Antworten
  • 200

    The company.

  • 401

    The key is missing, invalid, revoked or its account is suspended.

  • 404

    No such record in this account.

  • 429

    More than 60 requests in a minute with this key.

curl -X GET "https://freeprivacypolicy.app/api/v1/companies/42" \
  -H "Authorization: Bearer $FPP_API_KEY" \
  -H "Accept: application/json"
200-Antwort
{
    "data": {
        "id": 42,
        "company_name": "Acme Labs Ltd.",
        "email": "[email protected]",
        "address": "1 Market Street, Lisbon, Portugal",
        "about": "Acme Labs builds productivity apps for small teams.",
        "ads_txt": "google.com, pub-1234567890123456, DIRECT, f08c47fec0942fa0",
        "app_ads_txt": "google.com, pub-1234567890123456, DIRECT, f08c47fec0942fa0",
        "show_resources_publicly": true,
        "logo_url": null,
        "policies_count": 2,
        "created_at": "2026-09-01T12:00:00+00:00",
        "updated_at": "2026-09-20T08:30:00+00:00"
    }
}

Update a company

PATCH /companies/{id}

Only the fields you send change. ads_txt and app_ads_txt replace the whole file: send the current lines too when adding one. The policy pages show the new details at once; their text is not regenerated.

Parameter
  • id integer in path erforderlich

    The company id.

Body CompanyUpdate
  • company_name string

  • email string

  • address string | null

  • about string | null

  • ads_txt string | null

  • app_ads_txt string | null

  • show_resources_publicly boolean

Antworten
  • 200

    The updated company.

  • 401

    The key is missing, invalid, revoked or its account is suspended.

  • 404

    No such record in this account.

  • 422

    The request is invalid. errors lists the messages per field.

  • 429

    More than 60 requests in a minute with this key.

curl -X PATCH "https://freeprivacypolicy.app/api/v1/companies/42" \
  -H "Authorization: Bearer $FPP_API_KEY" \
  -H "Accept: application/json" \
  -H "Content-Type: application/json" \
  -d '{
    "app_ads_txt": "google.com, pub-1234567890123456, DIRECT, f08c47fec0942fa0\napplovin.com, 0123456789abcdef, DIRECT"
}'
Request-Body: Replace the app-ads.txt lines
{
    "app_ads_txt": "google.com, pub-1234567890123456, DIRECT, f08c47fec0942fa0\napplovin.com, 0123456789abcdef, DIRECT"
}
200-Antwort
{
    "data": {
        "id": 42,
        "company_name": "Acme Labs Ltd.",
        "email": "[email protected]",
        "address": "1 Market Street, Lisbon, Portugal",
        "about": "Acme Labs builds productivity apps for small teams.",
        "ads_txt": "google.com, pub-1234567890123456, DIRECT, f08c47fec0942fa0",
        "app_ads_txt": "google.com, pub-1234567890123456, DIRECT, f08c47fec0942fa0",
        "show_resources_publicly": true,
        "logo_url": null,
        "policies_count": 2,
        "created_at": "2026-09-01T12:00:00+00:00",
        "updated_at": "2026-09-20T08:30:00+00:00"
    }
}

Delete a company

DELETE /companies/{id}

Deletes the company with its logo and its ads.txt and app-ads.txt lines. Policies that used it stay online without a company, using the contact details saved with them.

Parameter
  • id integer in path erforderlich

    The company id.

Antworten
  • 204

    Deleted.

  • 401

    The key is missing, invalid, revoked or its account is suspended.

  • 404

    No such record in this account.

  • 429

    More than 60 requests in a minute with this key.

curl -X DELETE "https://freeprivacypolicy.app/api/v1/companies/42" \
  -H "Authorization: Bearer $FPP_API_KEY" \
  -H "Accept: application/json"

204 hat keinen Body.

Fehler

Fehler sind JSON mit einem message. Validierungsfehler ergänzen errors, nach Feld geordnet.

Status Wann
401 Nicht authentifiziert Der Schlüssel fehlt, ist falsch, wurde durch einen neueren ersetzt oder sein Konto ist gesperrt. Erstellen Sie einen neuen Schlüssel und aktualisieren Sie Ihr Secret.
404 Nicht gefunden In diesem Konto gibt es keine Richtlinie und kein Unternehmen mit diesem Slug oder dieser ID. Listen Sie Ihre Datensätze mit GET /policies oder GET /companies auf.
422 Validierung fehlgeschlagen Ein Feld fehlt oder ist ungültig. errors listet die Meldungen pro Feld. Prüfen Sie die Schlüssel mit GET /options.
429 Zu viele Anfragen Mehr als 60 Anfragen pro Minute mit demselben Schlüssel. Warten Sie die Sekunden aus Retry-After ab und versuchen Sie es erneut.
5xx Serverfehler Bei uns ist ein Fehler aufgetreten. Wiederholen Sie mit wachsender Verzögerung. Prüfen Sie vor dem Wiederholen eines POST per GET, dass er nicht durchgegangen ist.
422-Antwort
{
    "message": "The selected product type is invalid.",
    "errors": {
        "product_type": [
            "The selected product type is invalid."
        ]
    }
}

Paginierung und Limits

  • Listen sind paginiert. GET /policies und GET /companies akzeptieren page und per_page (1 bis 100, Standard 25).
  • links.next folgen folgen, bis es null ist. meta.total zählt alle Datensätze.
  • 60 Anfragen pro Minute pro Schlüssel. Ein 429 gibt in Retry-After an, wie lange Sie warten müssen.
  • Nur JSON. Senden Sie Accept: application/json und, mit Body, Content-Type: application/json.
GET /policies
{
    "data": [
        "…"
    ],
    "links": {
        "first": "https://freeprivacypolicy.app/api/v1/policies?page=1",
        "last": "https://freeprivacypolicy.app/api/v1/policies?page=3",
        "prev": null,
        "next": "https://freeprivacypolicy.app/api/v1/policies?page=2"
    },
    "meta": {
        "current_page": 1,
        "from": 1,
        "last_page": 3,
        "path": "https://freeprivacypolicy.app/api/v1/policies",
        "per_page": 25,
        "to": 25,
        "total": 61
    }
}

Versionierung und Änderungen

Die Version steht im Pfad: /api/v1. Innerhalb von v1 fügen wir nur hinzu, etwa neue Felder, neue Endpunkte und neue Dienste oder Abschnitte in GET /options. Ignorieren Sie also Felder, die Sie nicht kennen. Eine Änderung, die Clients brechen könnte, erscheint als /api/v2, v1 läuft weiter.

  1. 1.0.0, September 2026

    Persönliche Schlüssel aller Konten, gemeinsam mit dem MCP-Server genutzt. Neu: GET /me, GET /options, Auflisten und Löschen von Richtlinien, company_id und published bei Richtlinien sowie die Unternehmens-Endpunkte.