Build a vCard QR payload string
Turn a name, phone number, email address, and organization into a clean vCard 3.0 payload designed for QR code workflows.
Run — free
The result is a deterministic text string with the required vCard markers, safe escaping, and interoperable line endings. Paste that payload into a QR encoder or pass it to the next step in an automated pipeline. A name is required, while every other contact field is optional, so the same operation works for a minimal personal card or a more complete business contact.
Build the contact payload before generating the QR code
A contact QR code normally contains structured text rather than an image-specific contact format. This capability creates that structured layer for you: a vCard 3.0 payload beginning with BEGIN:VCARD, declaring VERSION:3.0, providing the required formatted name, and ending with END:VCARD. Supply a non-empty name and optionally add a phone number, email address, and organization. Blank optional values are left out instead of producing meaningless empty properties. The returned payload can then become the text input to any standards-aware QR code encoder. Keeping payload construction separate from image generation is useful because you can inspect, store, test, or reuse the contact data before choosing QR dimensions, error correction, colors, or output format. It also makes failures easier to diagnose: if a scanner recognizes the vCard text but the printed symbol is hard to read, the problem belongs to QR rendering rather than contact formatting. The operation is deterministic, so identical inputs produce identical payload strings every time.
Understand escaping, line endings, and optional properties
vCard values are not arbitrary lines of text. Backslashes, commas, semicolons, and embedded line breaks have structural meanings, so raw concatenation can change the contact or produce a payload that different address-book applications interpret inconsistently. This builder escapes those characters in every supplied value and uses CRLF line endings expected by the vCard format. A line break inside an organization or name becomes an escaped newline within one property rather than an accidental new vCard property. The name is written as FN, the display-name property required for this compact contact card. Phone, email, and organization become TEL, EMAIL, and ORG only when their trimmed values are non-empty. Input strings are trimmed at their outer edges, but meaningful characters within each value remain intact. The output also includes a final CRLF after END:VCARD, which makes the payload suitable for systems that expect a conventionally terminated text record. These choices favor a small, predictable QR payload while preserving the contact information supplied by the caller.
Use the payload reliably in QR and automation workflows
Take the returned payload field exactly as produced and provide it as the text content of your QR generator. Do not JSON-stringify it a second time or replace the line endings with visible slash characters; the QR symbol must encode the actual vCard text. After rendering, test the code with more than one camera or contact application when it will be printed or distributed broadly. Scanner behavior, print size, contrast, and QR error-correction settings are outside this capability, even though they affect the final experience. For automation, keep the structured source fields alongside the generated payload so a contact change can regenerate the card cleanly instead of editing encoded text. Validate email and telephone semantics upstream if your product requires strict business rules: this operation treats them as contact strings and focuses on vCard-safe serialization. The API costs $0.002 for each successful request, while the browser experience can run the same pure transformation locally. Invalid calls with an empty or whitespace-only name return an input error instead of creating a contact that address books cannot label usefully.
What you can do with it
Create a digital business card
Turn a professional identity and direct contact details into the text layer for a scannable business-card QR code.
Add contact sharing to event badges
Generate consistent vCard payloads from attendee records before rendering individual QR codes onto badges or passes.
Automate staff directory assets
Rebuild QR-ready contact payloads whenever a staff member's phone, email, or organization changes.
FAQ
Which vCard version does the payload use?
It explicitly declares VERSION:3.0 and emits a compact vCard record with FN plus any supplied TEL, EMAIL, and ORG properties.
Can I omit the phone, email, or organization?
Yes. Those three fields are optional, and an omitted or blank optional field does not create an empty property line.
Why is the name required?
The name supplies the formatted-name property that identifies the contact. An empty or whitespace-only name returns an invalid-input error.
Does this operation generate the QR image?
No. It returns the standards-formatted payload string that you pass to a separate QR code generator.
Are commas and line breaks handled safely?
Yes. Backslashes, commas, semicolons, and embedded newlines are escaped before each contact property is assembled.
How much does the API request cost?
Each successful API request costs $0.002. The same deterministic transformation can also run in the browser experience.
For developers — API access
Everything on this page is available programmatically. This section is for teams who want to wire it into their own systems; everyone else can just use the tool above.
API endpoint
Prefer to automate it? One authenticated POST creates the task; the result comes back by webhook or a signed link. The same capability also runs here on the web, by email and from Telegram — and soon from our app too.
Call it from your stack
curl -X POST https://api.kit.forhosting.com/enc/qr-vcard-payload \
-H "Authorization: Bearer $KIT_KEY" \
-H "Content-Type: application/json" \
-d '{"name":"Ada Lovelace"}'const res = await fetch("https://api.kit.forhosting.com/enc/qr-vcard-payload", {
method: "POST",
headers: {
"Authorization": `Bearer ${process.env.KIT_KEY}`,
"Content-Type": "application/json"
},
body: JSON.stringify({
"name": "Ada Lovelace"
})
});
const { task_id } = await res.json();import os, requests
res = requests.post(
"https://api.kit.forhosting.com/enc/qr-vcard-payload",
headers={"Authorization": f"Bearer {os.environ['KIT_KEY']}"},
json={
"name": "Ada Lovelace"
},
)
task_id = res.json()["task_id"]<?php
$res = file_get_contents("https://api.kit.forhosting.com/enc/qr-vcard-payload", false, stream_context_create([
"http" => [
"method" => "POST",
"header" => "Authorization: Bearer " . getenv("KIT_KEY") . "\r\nContent-Type: application/json",
"content" => '{"name":"Ada Lovelace"}',
],
]));
$task = json_decode($res, true);body := bytes.NewBufferString(`{"name":"Ada Lovelace"}`)
req, _ := http.NewRequest("POST", "https://api.kit.forhosting.com/enc/qr-vcard-payload", body)
req.Header.Set("Authorization", "Bearer "+os.Getenv("KIT_KEY"))
req.Header.Set("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)Example request
{
"name": "Ada Lovelace"
}Example response
{
"task_id": "tsk_a1b2c3d4e5f6a1b2c3d4e5f6",
"type": "enc.qr_vcard_payload",
"status": "queued",
"_links": {
"result": "/tasks/tsk_…/result"
}
}The API is asynchronous: the call returns a task_id immediately and the result arrives by webhook. Polling is capped at 1 req/s per task.
Pricing
Published price — no tokens, no invented credits. A failed task is never charged.
Errors
| HTTP | Code | Meaning |
|---|---|---|
401 | unauthorized | Missing or invalid API key. |
402 | insufficient_balance | Your balance doesn't cover the task price. |
404 | unknown_type | That task type doesn't exist. |
429 | rate_limited | Too many requests. Use the webhook instead of polling. |