DPP Agent docs

Tenants — brand profile, members, domains

A tenant is one brand on DPP Agent. Slugs are immutable per EN 18219 §4.2 (URL stability) — once set, your passport URLs never change.

Object shape

{
  "id": "tnt_8d3a4f91-…",
  "slug": "bang-olufsen",
  "name": "Bang & Olufsen",
  "industry": "electronics",
  "country": "DK",
  "economic_operator_id": "LEI:54930WJYK7BL2VMM6537",
  "facility_id": null,
  "custom_domain": null,
  "tier": "light",
  "brand_theme": { "template_id": "electronics-premium", "assets": {} },
  "logo_url": "https://…/bo-logo.svg",
  "created_at": "2026-05-01T08:00:00.000Z"
}

Read

GET /api/v1/tenants/{id}
Authorization: Bearer dpp_live_…

Returns the full object. Bearer token must be scoped to the same tenant — otherwise 403 forbidden.

Update editable fields

PATCH /api/v1/tenants/{id}
{
  "name": "Bang & Olufsen A/S",
  "industry": "electronics",
  "country": "DK",
  "economic_operator_id": "LEI:54930WJYK7BL2VMM6537",
  "facility_id": "DUNS:123456789"
}

Slugs and IDs are locked. Custom-domain changes go through their own endpoint (below).

Custom domains

Custom-tier plans can publish passports at a brand-owned domain (e.g. dpp.example.com) instead of {slug}.dpp.dppagent.com.

Register a domain:

POST /api/v1/tenants/{id}/custom-domain
{ "domain": "dpp.example.com" }

Response includes the DNS records to add (one CNAME, one TXT for verification):

{
  "status": "pending_verification",
  "dns_records": [
    { "type": "CNAME", "name": "dpp.example.com", "value": "cname.dppagent.com" },
    { "type": "TXT",   "name": "_dppagent.dpp.example.com", "value": "verify=a8b1c2…" }
  ]
}

Verify once DNS propagates:

POST /api/v1/tenants/{id}/custom-domain-verify

Returns 200 with status: "active" when the CNAME + TXT both resolve correctly. TLS certificate provisioning is automatic.

Members

POST /api/v1/tenants/{id}/members
{
  "email": "operator@example.com",
  "role": "admin"
}

Roles: viewer, editor, admin, owner. See Roles & access for the full permission matrix.

Bulk member listing and removal are in the dashboard for now; API endpoints ship in v1.2.

Analytics

GET /api/v1/tenants/{id}/analytics?days=30

Tenant-wide rollup of DPP counters and scan totals across all the brand's passports. Shape mirrors the per-DPP analytics payload — see the DPPs reference for the field-by-field breakdown.

Brand assets

Logo + brand mark + favicon URLs are stored on the tenant row (logo_url, brand_theme.assets.*). Edit them through the dashboard or via PATCH:

{
  "logo_url": "https://cdn.example.com/logo.svg",
  "brand_theme": {
    "template_id": "electronics-premium",
    "assets": {
      "header_logo_url": "https://cdn.example.com/logo-dark.svg",
      "footer_logo_url": "https://cdn.example.com/logo-mono.svg",
      "favicon_url":     "https://cdn.example.com/favicon.ico",
      "brand_mark_url":  "https://cdn.example.com/mark.svg"
    }
  }
}

Assets are referenced from QR-code center logos and label wordmarks automatically when nothing more specific is set.