proofsdocscomparepricinglog in

Documentation

Learn how to integrate proof.holdings

Core Primitives
The mental model in one page
API Reference
Complete API documentation
SDKs
Official client libraries
Smart Reuse
Skip re-verification with existing proofs
Multi-Profile System
Multiple public profiles per account
Message Templates
Custom branding and message templates per project
Comparison
vs SMS OTP, TOTP, WebAuthn
Pricing
Plans and pricing tiers
Security
Threat model and guarantees
MCP Server
167 tools for AI agents
Integrations
n8n, Zapier, Make, and custom integrations
Proof of Me
Anti-impersonation reverse verification via trusted Circle members
Proof of Delegation
A proven domain authorizing an artifact, and how to verify or withdraw it
Resources
GitHub Docs
Status

Multi-Profile System

Create multiple public profiles with independent settings and verified assets


Overview

Users can create multiple public profiles, each with its own display name, bio, theme, and set of verified assets. This supports use cases like separating personal and business identities, or managing multiple brands under one account.

Each profile gets a unique shareable URL (/p/{profileId}) and can optionally claim a vanity username (/@{username}).


Endpoints

All profile endpoints require JWT authentication and are scoped to the authenticated user.

Base path: https://api.proof.holdings/api/v1/me

MethodEndpointPurpose
GET/me/profilesList all profiles
POST/me/profilesCreate new profile
GET/me/profiles/:profileIdGet specific profile
PATCH/me/profiles/:profileIdUpdate profile
DELETE/me/profiles/:profileIdDelete profile
POST/me/profiles/:profileId/primarySet as primary profile

One further endpoint manages which proofs a profile displays. It is not under the /me base path above — give it in full:

MethodEndpointPurpose
PUT/api/v1/profiles/profiles/:profileId/proofsUpdate profile's public proofs

Create Profile

POST /api/v1/me/profiles

Request Body

ParameterTypeRequiredDescription
display_namestringNoDisplay name (max 100 chars)
biostringNoProfile bio (max 500 chars)
avatar_urlstringNoHTTPS URL or base64 data URI
business_namestringNoBusiness name (max 100 chars)
is_businessbooleanNoWhether this is a business profile
is_publicbooleanNoWhether the profile is publicly visible
is_primarybooleanNoSet as the primary profile
themeobjectNoVisual theme (see Theme Object)
email_themestringNodark or light — how this project's emails look (unset renders as dark)
support_emailstringNoWhere recipients of this project's messages can reach it; fills {{support_email}}
bash
curl -X POST https://api.proof.holdings/api/v1/me/profiles \
  -H "Cookie: session=eyJ..." \
  -H "Content-Type: application/json" \
  -d '{
    "display_name": "Acme Corp",
    "bio": "Verified digital presence for Acme Corporation",
    "is_business": true,
    "business_name": "Acme Corp",
    "is_public": true,
    "theme": {
      "primary_color": "#3B82F6",
      "background_type": "gradient",
      "gradient_start": "#1E3A5F",
      "gradient_end": "#0F172A",
      "font_style": "modern"
    }
  }'

Response

json
{
  "id": "64a1b2c3d4e5f6a7b8c9d0e1",
  "profile_id": "k7x2m9p4",
  "display_name": "Acme Corp",
  "bio": "Verified digital presence for Acme Corporation",
  "is_business": true,
  "business_name": "Acme Corp",
  "is_public": true,
  "is_primary": false,
  "email_theme": null,
  "support_email": null,
  "verification_level": "basic",
  "public_proofs": [],
  "custom_links": [],
  "theme": {
    "primary_color": "#3B82F6",
    "background_type": "gradient",
    "gradient_start": "#1E3A5F",
    "gradient_end": "#0F172A",
    "font_style": "modern"
  },
  "view_count": 0,
  "created_at": "2026-02-06T12:00:00Z",
  "updated_at": "2026-02-06T12:00:00Z"
}

Update Profile

PATCH /api/v1/me/profiles/:profileId

Accepts any subset of the create fields, plus additional settings:

ParameterTypeDescription
show_verification_datesbooleanShow when each asset was verified
show_proof_channelsbooleanShow which channel was used
custom_linksarrayUp to 20 custom links (see below)

support_email also accepts null, which clears it.

Custom Links

Each link in the custom_links array:

FieldTypeRequiredDescription
titlestringYesLink title (max 100 chars)
urlstringYesLink URL (max 500 chars)
iconstringNoIcon identifier (max 50 chars)
is_visiblebooleanNoWhether link is shown publicly
display_ordernumberNoSort order (0-based)
bash
curl -X PATCH https://api.proof.holdings/api/v1/me/profiles/64a1b2c3d4e5f6a7b8c9d0e1 \
  -H "Cookie: session=eyJ..." \
  -H "Content-Type: application/json" \
  -d '{
    "bio": "Updated bio for Acme",
    "custom_links": [
      { "title": "Website", "url": "https://acme.com", "display_order": 0 },
      { "title": "Support", "url": "https://acme.com/support", "display_order": 1 }
    ]
  }'

Update Public Proofs

PUT /api/v1/profiles/profiles/:profileId/proofs

Control which verified assets appear on a profile and how they are displayed.

Request Body

ParameterTypeDescription
proofsarrayUp to 50 proof display settings

Each proof in the array:

FieldTypeRequiredDescription
asset_idstringYesID of the verified asset
is_visiblebooleanNoWhether to show on profile
mask_levelstringNofull, partial, or hidden
display_ordernumberNoSort order (0-based)
labelstringNoCustom label (e.g., "Support Phone")
bash
curl -X PUT https://api.proof.holdings/api/v1/profiles/profiles/64a1b2c3d4e5f6a7b8c9d0e1/proofs \
  -H "Cookie: session=eyJ..." \
  -H "Content-Type: application/json" \
  -d '{
    "proofs": [
      {
        "asset_id": "507f1f77bcf86cd799439011",
        "is_visible": true,
        "mask_level": "partial",
        "display_order": 0,
        "label": "Main Phone"
      },
      {
        "asset_id": "507f1f77bcf86cd799439012",
        "is_visible": true,
        "mask_level": "full",
        "display_order": 1,
        "label": "Business Domain"
      }
    ]
  }'

Privacy Masking

LevelPhoneEmailDomain
full+37069199199[email protected]example.com
partial+3••••9199us•••@example.comexample.com
hiddenVerified PhoneVerified EmailVerified Domain

Theme Object

FieldTypeValues
primary_colorstringHex color (e.g., #3B82F6)
background_typestringsolid or gradient
background_colorstringHex color (solid backgrounds)
gradient_startstringHex color (gradient start)
gradient_endstringHex color (gradient end)
font_stylestringdefault, modern, or classic

Public Profile URLs

Profiles are publicly accessible without authentication:

URL PatternExample
/p/:profileIdhttps://proof.holdings/p/k7x2m9p4
/@:usernamehttps://proof.holdings/@acmecorp

Verification Levels

Profiles automatically earn verification badges based on verified asset count:

LevelRequirement
basicDefault for new profiles
verifiedMultiple verified asset types
businessBusiness profile with verified domain

Notes

  • Each user can have multiple profiles, but only one can be primary
  • Every outbound message carries exactly one project's branding — name, logo, colour, email theme, support email and message templates. A key bound to a project always uses that project; an account-wide key or a dashboard session uses the project it names, else the primary profile. There is no account-wide branding
  • A key bound to a sub-account reads every profile but changes only its own; see Sub-accounts and API keys
  • Deleting a profile does not revoke the underlying verified assets
  • Profile IDs are cryptographically random 8-character strings
  • Username claiming is rate-limited to 5 attempts per minute

Related

Smart ReuseAPI Reference
Last updated October 15, 2026
Proof Holdings

The verification API for humans and AI agents — every verification a signed proof you hold.

A service of LT Telecom (UAB "LT telekomunikacijos")

PrivacyTermsDPASubprocessorsStatusGitHubLinkedIn