Link pages
Build a link page at yourname.cvinfo.me from a simple form or JSON — themes, links, info blocks and analytics.
A link page lives at https://yourname.cvinfo.me/ and costs 2 credits once. Editing and republishing are free.
Create one#
- Pages & decks → Link page, choose the address (
yourname) and create it. - Fill in the editor: name, headline, location, email, photo URL, theme, bio, links and info blocks.
- Watch the live preview, then press Save & publish.
The address can't be changed later; everything else can.
Fields#
| Field | Notes |
|---|---|
| Name | Required, the page heading |
| Headline | One line, e.g. "Senior data engineer" |
| Photo URL | Must be https:// |
| Bio | Markdown |
| Links | One per line in the editor: Label | https://…. Icons are picked from the URL |
| Info blocks | Markdown; each ## Title starts a new block |
| Theme | cvinfo, midnight, light or sunset |
Show in search engines#
New pages are hidden from Google (noindex). Switch on Show in search engines in the editor if you want the page to be found. Links on your page carry rel="ugc nofollow".
Versions and rollback#
Every publish creates a version. On Pages & decks you can roll back to any of the last five.
Tracked links#
Create a tracked link per application (1 credit) to see which company opened your page.
JSON spec#
Behind the editor (and the AI assistant) every page is this JSON:
{
"name": "Jane Doe",
"headline": "Senior data engineer · Python, Spark, dbt",
"location": "Berlin",
"email": "jane@example.com",
"avatar_url": "https://example.com/jane.jpg",
"bio": "I build **reliable data platforms**. Currently open to new roles.",
"theme": "cvinfo",
"links": [
{
"label": "LinkedIn",
"url": "https://linkedin.com/in/janedoe",
"icon": "linkedin"
},
{
"label": "GitHub",
"url": "https://github.com/janedoe",
"icon": "github"
},
{
"label": "Download my CV",
"url": "https://example.com/cv.pdf",
"icon": "cv"
}
],
"sections": [
{
"title": "Experience",
"markdown": "- **Acme** — Lead data engineer (2021–)\n- **Initech** — Data engineer (2018–2021)"
}
],
"video": {
"source": "video:0b6e1e8a-6f0e-4a3c-9d2d-2f9c8a1b4d77",
"caption": "60 seconds on why this role"
},
"deck": {
"slug": "jane-talk",
"label": "My fraud-scoring project"
},
"references": [
{
"name": "Ada Fischer",
"role": "CTO",
"company": "Acme GmbH",
"contact": "ada@acme.example",
"quote": "Jane turned our data swamp into a platform."
}
],
"gate": {
"enabled": true,
"title": "Enter your work email to unlock"
}
}
Full JSON Schema
{
"$schema": "https://json-schema.org/draft/2020-12/schema",
"title": "cvinfo structured page",
"type": "object",
"additionalProperties": false,
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 80,
"description": "Display name, the page heading."
},
"headline": {
"type": "string",
"maxLength": 140,
"description": "One line under the name, e.g. 'Senior data engineer'."
},
"location": {
"type": "string",
"maxLength": 80
},
"email": {
"type": "string",
"maxLength": 254,
"format": "email",
"description": "Shown as a mailto button."
},
"avatar_url": {
"type": "string",
"maxLength": 500,
"pattern": "^https://\\S+$",
"description": "https URL of a square photo."
},
"avatar_file": {
"type": "string",
"maxLength": 40,
"pattern": "^avatar-[0-9a-f]{8}\\.jpg$",
"description": "Read-only: a photo uploaded in the editor, served from the page's own host. Set by the app, not by API clients."
},
"bio": {
"type": "string",
"maxLength": 3000,
"description": "Markdown."
},
"theme": {
"enum": [
"midnight",
"light",
"cvinfo",
"sunset"
],
"default": "cvinfo"
},
"links": {
"type": "array",
"maxItems": 30,
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"label",
"url"
],
"properties": {
"label": {
"type": "string",
"minLength": 1,
"maxLength": 60
},
"url": {
"type": "string",
"maxLength": 500,
"pattern": "^(https?://|mailto:)\\S+$"
},
"icon": {
"enum": [
"link",
"linkedin",
"github",
"gitlab",
"x",
"mastodon",
"bluesky",
"youtube",
"instagram",
"website",
"email",
"cv",
"calendar",
"phone",
"portfolio",
"blog"
]
}
}
}
},
"sections": {
"type": "array",
"maxItems": 12,
"description": "Info blocks under the links (experience, skills, projects\u2026).",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"title",
"markdown"
],
"properties": {
"title": {
"type": "string",
"minLength": 1,
"maxLength": 80
},
"markdown": {
"type": "string",
"maxLength": 6000
}
}
}
},
"video": {
"type": "object",
"additionalProperties": false,
"required": [
"source"
],
"description": "An intro video at the top of the page: 'video:<id>' picks one from your video library. Upload and review happen in the app (cvinfo.me/videos/), which is also where each video's id is shown. The page streams it from cvinfo.me through an expiring URL, and only while it is approved. 'profile' and 'link:<uuid>' are still understood \u2014 they are what specs said before videos became reusable.",
"properties": {
"source": {
"type": "string",
"maxLength": 80,
"pattern": "^(profile|link:[0-9a-f-]{36}|video:[0-9a-f-]{36})$"
},
"caption": {
"type": "string",
"maxLength": 140
}
}
},
"deck": {
"type": "object",
"additionalProperties": false,
"required": [
"slug"
],
"description": "One of your own presentations, shown as a card that opens it.",
"properties": {
"slug": {
"type": "string",
"maxLength": 63,
"pattern": "^[a-z0-9-]+$"
},
"label": {
"type": "string",
"maxLength": 80
}
}
},
"references": {
"type": "array",
"maxItems": 8,
"description": "People who vouch for you. Hidden behind the e-mail gate when it is on.",
"items": {
"type": "object",
"additionalProperties": false,
"required": [
"name"
],
"properties": {
"name": {
"type": "string",
"minLength": 1,
"maxLength": 80
},
"role": {
"type": "string",
"maxLength": 120
},
"company": {
"type": "string",
"maxLength": 80
},
"contact": {
"type": "string",
"maxLength": 254
},
"quote": {
"type": "string",
"maxLength": 400
}
}
}
},
"css": {
"type": "string",
"maxLength": 50000,
"description": "Custom CSS theme, applied after the built-in theme. Sanitised: no @import, no external url() \u2014 only uploaded images as url(upload:<id>)."
},
"gate": {
"type": "object",
"additionalProperties": false,
"description": "Ask visitors for a work e-mail before the references are shown.",
"properties": {
"enabled": {
"type": "boolean",
"default": false
},
"title": {
"type": "string",
"maxLength": 120
}
}
}
}
}