LCX
LiveCard Exchange

LCX 1.0 Specification

The complete LiveCard Exchange Standard. This document defines the data model, QR deep link format (lcx://v1?p=…), media assets, layout system, server protocol, authentication, caching, and security requirements.

LiveCard Exchange (LCX) Standard

Version: 1.0 Status: Draft Date: 2026-04-06 Authors: Componera (PTY) LTD Document Identifier: LCX-1.0 MIME Type: application/vnd.lcx.card+json


Abstract

The LiveCard Exchange (LCX) Standard defines an interoperable protocol for creating, sharing, and live-updating digital business cards across platforms and applications. It specifies a JSON-based data model for business card content, a layout system for visual rendering, an lcx:// deep-link QR encoding format so operating systems can route scans to LCX-compatible apps, and a REST-based server protocol that enables cards to update in real time after they have been exchanged.

LCX is designed for two audiences: developers building Card Provider platforms (services that host and manage business cards) and developers building Card Consumer applications (apps that store, display, and synchronize received cards). By adhering to this standard, any Card Provider can issue cards that any Card Consumer can display and keep up to date — regardless of who built either system.


Table of Contents

  1. Introduction
  2. Terminology and Conventions
  3. Card Data Model
  4. QR Code Encoding
  5. Media Assets
  6. Card Layout and Positioning
  7. Update Server Protocol
  8. Authentication
  9. Caching and Offline Behavior
  10. Security Considerations
  11. Extensibility and Versioning
  12. Appendix A: JSON Schema
  13. Appendix B: Example Card Payload
  14. Appendix C: Example QR Code Payload
  15. Appendix D: Example HTTP Exchange
  16. Appendix E: MIME Type Registration

1. Introduction

1.1 Problem Statement

Physical business cards become outdated the moment they are printed. A change in phone number, job title, or company branding renders every previously distributed card inaccurate. Digital alternatives exist, but they are fragmented: each platform uses its own proprietary format, making it impossible for a card created on one service to be reliably consumed by another.

There is no open, interoperable standard that simultaneously addresses:

  • Structured card data (contact details, social links, addresses)
  • Visual presentation (layout, images, branding)
  • Live updates (fetching the latest card data from a server after the initial exchange)
  • Offline resilience (caching card data for use when connectivity is unavailable)
  • Secure sharing (exchanging cards via QR codes with optional access control)

1.2 Goals

LCX aims to:

  1. Define a universal data model for digital business cards that is rich enough to represent real-world card designs.
  2. Specify an absolute-positioning layout system that gives card designers full creative control while remaining resolution-independent.
  3. Establish a QR code encoding format that enables instant card sharing between devices.
  4. Define a REST-based update protocol that allows cards to be refreshed from a server, ensuring recipients always see the latest information.
  5. Provide caching and offline requirements so that cards remain accessible even when the hosting server is unreachable.
  6. Support optional authentication for private or restricted cards.
  7. Be extensible so that future versions can add capabilities without breaking existing implementations.

1.3 Audience

This specification is intended for:

  • Card Provider developers — those building platforms where users create, manage, and host their digital business cards.
  • Card Consumer developers — those building applications (mobile apps, desktop clients, web viewers) that scan, store, display, and synchronize received business cards.

1.4 Scope

LCX 1.0 covers the data model, layout system, QR encoding, server protocol, caching behavior, and security considerations for digital business cards. It does not cover:

  • User account management or registration flows on Card Provider platforms.
  • The process of designing or editing a card (this is Provider-specific UI).
  • Token issuance or OAuth flows (authentication token provisioning is left to Card Providers).
  • Push notifications or WebSocket-based real-time subscriptions (polling via TTL is the v1.0 mechanism).

2. Terminology and Conventions

2.1 Key Terms

TermDefinition
CardA digital business card conforming to the LCX data model.
Card PayloadThe complete JSON document representing a Card, including data, media references, and layout.
Card ProviderA server or platform that hosts, manages, and serves Card Payloads. Providers expose an Update Endpoint from which Consumers fetch card data.
Card ConsumerAn application that scans, stores, displays, and synchronizes Cards received from Providers.
Card URIThe full URL of a Card's Update Endpoint, uniquely identifying where a Card's live data can be fetched.
Update EndpointThe HTTP(S) API endpoint on a Card Provider from which a Card Consumer retrieves the latest Card Payload.
Card IDA globally unique identifier (UUID v4) assigned to each Card by its Provider.
QR PayloadThe JSON object carried inside an LCX QR URI (after base64url decoding the p query parameter) that enables a Consumer to locate and fetch a Card.
LCX QR URIThe UTF-8 string encoded in a share QR code: an lcx:// deep link whose query parameter p holds a base64url-encoded QR Payload.
CanvasThe virtual coordinate space in which Card layout elements are positioned.
TTL (Time To Live)A value in seconds indicating how frequently a Consumer should re-fetch a Card from the Update Endpoint.

2.2 Notational Conventions

The keywords "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY", and "OPTIONAL" in this document are to be interpreted as described in RFC 2119.

2.3 Data Format Conventions

  • All JSON field names use camelCase.
  • All timestamps use ISO 8601 format in UTC (e.g., "2026-04-06T12:00:00Z").
  • All UUIDs follow UUID v4 format (e.g., "550e8400-e29b-41d4-a716-446655440000").
  • All colors are expressed as CSS-compatible strings: hex ("#FF5733"), rgba ("rgba(255, 87, 51, 0.8)"), or named colors ("white").
  • All URLs MUST be absolute and use the https scheme unless explicitly stated otherwise.

3. Card Data Model

The Card Payload is a JSON object that contains all information needed to display and update a business card. This section defines the structure of that object.

3.1 Top-Level Structure

{
  "lcxVersion": "1.0",
  "cardId": "<uuid>",
  "createdAt": "<iso8601>",
  "updatedAt": "<iso8601>",
  "ttl": 3600,
  "identity": { ... },
  "professional": { ... },
  "contacts": [ ... ],
  "addresses": [ ... ],
  "socials": [ ... ],
  "customFields": [ ... ],
  "bio": "<string>",
  "media": { ... },
  "layout": { ... }
}

3.2 Metadata Fields

FieldTypeRequiredDescription
lcxVersionstringREQUIREDThe LCX specification version this payload conforms to. For this specification: "1.0".
cardIdstring (UUID v4)REQUIREDGlobally unique identifier for this card, assigned by the Card Provider.
createdAtstring (ISO 8601)REQUIREDTimestamp of when the card was first created.
updatedAtstring (ISO 8601)REQUIREDTimestamp of the most recent modification to the card.
ttlintegerRECOMMENDEDSuggested re-fetch interval in seconds. Consumers SHOULD NOT poll the Update Endpoint more frequently than this value. Default assumption if omitted: 3600 (1 hour).

3.3 Identity Fields

The identity object contains personal identification information.

FieldTypeRequiredDescription
fullNamestringREQUIREDThe person's full display name as it should appear on the card.
preferredNamestringOPTIONALA shorter or informal name (e.g., "Jack" instead of "Jackson").
prefixstringOPTIONALName prefix or honorific (e.g., "Dr.", "Prof.", "Mr.").
suffixstringOPTIONALName suffix (e.g., "Jr.", "III", "PhD").
pronounsstringOPTIONALPreferred pronouns (e.g., "he/him", "she/her", "they/them").

3.4 Professional Fields

The professional object contains work-related information.

FieldTypeRequiredDescription
jobTitlestringOPTIONALThe person's job title or role.
departmentstringOPTIONALDepartment or division within the organization.
organizationstringOPTIONALThe name of the company or organization.
organizationUrlstring (URL)OPTIONALThe organization's website URL.

3.5 Contacts Array

The contacts array contains communication channels. Each entry is an object:

FieldTypeRequiredDescription
typestringREQUIREDThe contact method. MUST be one of: "phone", "email", "fax", "pager", "sms", "whatsapp", "telegram", "signal", "other".
valuestringREQUIREDThe contact value (phone number, email address, etc.). Phone numbers SHOULD use E.164 format (e.g., "+27821234567").
labelstringOPTIONALA human-readable label (e.g., "Work", "Personal", "Mobile").
preferredbooleanOPTIONALIf true, indicates this is the preferred contact method of this type. Defaults to false.

A Card Payload SHOULD contain at least one entry in the contacts array.

3.6 Addresses Array

The addresses array contains physical or mailing addresses. Each entry is an object:

FieldTypeRequiredDescription
labelstringOPTIONALA human-readable label (e.g., "Office", "Home", "Warehouse").
streetstringOPTIONALStreet address, including building/suite numbers.
citystringOPTIONALCity or locality.
statestringOPTIONALState, province, or region.
postalCodestringOPTIONALPostal or ZIP code.
countrystringOPTIONALCountry name or ISO 3166-1 alpha-2 code (e.g., "ZA", "US").
coordinatesobjectOPTIONALGeographic coordinates: { "lat": <number>, "lng": <number> }.

3.7 Socials Array

The socials array contains social media and professional network links. Each entry is an object:

FieldTypeRequiredDescription
platformstringREQUIREDThe platform identifier. RECOMMENDED values: "linkedin", "twitter", "x", "facebook", "instagram", "github", "youtube", "tiktok", "mastodon", "bluesky", "threads", "snapchat", "pinterest", "dribbble", "behance", "medium", "other". Custom platform identifiers MAY be used.
urlstring (URL)REQUIREDThe full URL to the person's profile on this platform.
handlestringOPTIONALThe person's username or handle on this platform (e.g., "@componera").

3.8 Custom Fields Array

The customFields array allows Card Providers to include arbitrary key-value data not covered by the standard fields. Each entry is an object:

FieldTypeRequiredDescription
labelstringREQUIREDA human-readable label for this field (e.g., "License Number", "Languages Spoken").
valuestringREQUIREDThe field value.
iconstring (URL)OPTIONALURL to an icon image representing this field.

3.9 Bio

FieldTypeRequiredDescription
biostringOPTIONALA free-text biography or description. Plain text only in v1.0. Consumers SHOULD display this with line breaks preserved.

4. QR Code Encoding

This section defines how a Card is shared between devices using QR codes.

The QR code MUST encode an LCX QR URI: a URI whose scheme is lcx, whose authority (host) identifies the QR transport revision, and whose query carries the card locator data. The scanned string therefore begins with lcx:// (or LCX://, etc.; see below), which allows mobile and desktop operating systems to offer Open in actions for apps that register the lcx URL scheme.

The QR code MUST NOT contain raw JSON as its entire payload. The JSON QR Payload (Sections 4.2–4.4) is embedded only after decoding.

Normative form:

lcx://v1?p=<base64url>
ComponentRequirement
Schemelcx. Per RFC 3986, scheme matching is case-insensitive. Producers MUST serialize the scheme as lowercase lcx. Consumers MUST accept lcx in any case (e.g., LCX://v1?... from a camera overlay).
Authorityv1 — LCX QR transport version aligned with the API path /lcx/v1/. Future standards MAY define lcx://v2?... without changing HTTP Card URIs until a future API version exists.
PathEmpty (no path segment after lcx://v1). Producers MUST NOT include a path; Consumers MAY ignore an empty path if present.
QueryExactly one REQUIRED parameter: p. The value is the base64url encoding (RFC 4648, Section 5; without padding characters =) of the UTF-8 octets of the QR Payload JSON document (Sections 4.2–4.4). Producers MUST use a compact JSON serialization (minimal whitespace). Additional query parameters are reserved for future LCX versions; Consumers MUST ignore unknown parameters.

Encoding steps (Card Provider):

  1. Build the QR Payload JSON object (Sections 4.2–4.4).
  2. Serialize to UTF-8 bytes with no insignificant whitespace (same logical JSON as a pretty-printed document).
  3. Encode those bytes with base64url and omit padding.
  4. Form the URI lcx://v1?p= followed by that string. The full URI is the QR symbol contents.

Decoding steps (Card Consumer):

  1. Obtain the scanned string (trim leading/trailing whitespace).
  2. Parse or pattern-match as a URI with scheme lcx (case-insensitive) and authority v1.
  3. Read the p query parameter. If missing or empty, fail the decode.
  4. Base64url-decode p to bytes. Implementations MUST accept omitted padding and MUST NOT require = padding.
  5. Interpret the bytes as UTF-8 and parse as JSON to obtain the QR Payload.
  6. Validate and use the QR Payload (Sections 4.3–4.4); fetch the Card from the HTTPS Card URI in the uri field using the same HTTP behavior as before (Section 7, Section 8).

The Card URI inside the JSON remains an https:// Update Endpoint URL (for example https://cards.example.com/lcx/v1/cards/{cardId}). Only the QR transport wrapping uses the lcx:// scheme; live fetch and caching are unchanged HTTP(S).

4.2 QR Payload Format (JSON)

After decoding the p parameter, the Consumer parses the following JSON structure:

{
  "lcx": "1",
  "uri": "https://cards.example.com/lcx/v1/cards/550e8400-e29b-41d4-a716-446655440000",
  "cid": "550e8400-e29b-41d4-a716-446655440000",
  "auth": "none",
  "token": null,
  "snapshot": {
    "fn": "Jane Smith",
    "title": "Chief Technology Officer",
    "org": "Componera (PTY) LTD"
  }
}

4.3 QR Payload Fields

FieldTypeRequiredDescription
lcxstringREQUIREDThe LCX major version number as a string. For this specification: "1". Consumers MUST check this field to determine compatibility.
uristring (URL)REQUIREDThe full Update Endpoint URL from which the complete Card Payload can be fetched.
cidstring (UUID)REQUIREDThe Card ID. MUST match the cardId in the Card Payload returned by the Update Endpoint.
authstringOPTIONALAuthentication method required to access the card. MUST be one of: "none" (default), "bearer", "query". If omitted, Consumers MUST assume "none".
tokenstringOPTIONALThe authentication token. REQUIRED if auth is "bearer" or "query". MUST be null or omitted if auth is "none".
snapshotobjectOPTIONALA minimal preview of the card for instant display before the full payload is fetched from the server. See Section 4.4.

4.4 Snapshot Object

The snapshot provides enough data to render a basic preview immediately upon scanning, before any network request completes.

FieldTypeRequiredDescription
fnstringREQUIREDFull name (abbreviated key to save space).
titlestringOPTIONALJob title.
orgstringOPTIONALOrganization name.
emailstringOPTIONALPrimary email address.
phonestringOPTIONALPrimary phone number.

Providers SHOULD include the snapshot object. The snapshot exists purely for UX optimization and MUST NOT be treated as authoritative data. Consumers MUST replace snapshot data with the full Card Payload once it is fetched from the Update Endpoint.

4.5 Registering the lcx Protocol (Consumers)

LCX-compatible Card Consumers SHOULD register a handler for the lcx URL scheme on every platform they support, so that when the user scans a share QR code, the OS can open the Consumer directly with the full LCX QR URI.

The following notes are informative; they rest on platform documentation that may evolve. Implementers MUST consult current vendor guides.

4.5.1 iOS and iPadOS

  • Declare the URL scheme lcx under CFBundleURLTypes / CFBundleURLSchemes in Info.plist.
  • Implement the appropriate open-URL callback (application(_:open:options:) on UIApplicationDelegate, or scene(_:openURLContexts:) on UISceneDelegate for multi-window apps).
  • Parse the incoming URL as an LCX QR URI (Section 4.1), then run the decoding pipeline (Section 4.1) before fetching the Card over HTTPS.

Universal Links (https://...) are separate from custom schemes; LCX 1.0 does not require Universal Links. A Consumer MAY additionally associate an https host with the app for non-QR entry points, but the normative share QR format remains lcx://.

4.5.2 Android

  • Declare an Activity (or NavDeepLink) with an <intent-filter>: action android.intent.action.VIEW, categories DEFAULT and BROWSABLE, and <data android:scheme="lcx" android:host="v1" />.
  • Read the intent URI in onCreate / onNewIntent; parse and decode per Section 4.1.
  • App Links verify https hosts; they do not replace custom-scheme handling for lcx://.

4.5.3 macOS and Windows desktop

  • macOS: Same URL-type registration as iOS in the app bundle; handle incoming URLs via NSApplication / AppDelegate open-URL APIs.
  • Windows: Register a custom URL protocol for lcx so ShellExecute / the default browser handoff passes the string to the registered LCX Consumer.

4.5.4 Web browsers and generic scanners

  • Many in-browser QR scanners produce a string and navigate to it. For lcx://, the browser or OS typically resolves the scheme to a registered native app. Pure web apps cannot reliably “claim” arbitrary custom schemes the way native apps do; hybrid or native Consumers should handle lcx:// in the native shell and pass the decoded payload to embedded WebViews if needed.
  • Camera / scanner apps pass the scanned string to the platform URL dispatcher; registering lcx is what enables Open with LCX app behavior.

4.6 QR Code Requirements

  1. Encoding mode: The QR code MUST encode the LCX QR URI (Section 4.1) as a UTF-8 byte string.
  2. Error correction: The QR code MUST use error correction level M (15% recovery) or higher. Level Q (25%) is RECOMMENDED for printed materials.
  3. Maximum QR Payload size: The decoded QR Payload JSON (UTF-8 bytes after base64url decode) SHOULD NOT exceed 2,048 bytes (2 KB) when serialized without insignificant whitespace. The full LCX QR URI is longer than the JSON alone (prefix + base64url overhead); Providers SHOULD still target compact payloads so the QR symbol stays scannable at reasonable print sizes.
  4. Minimum module size: When rendered for display or print, each QR module (dot) SHOULD be at least 0.75mm wide to ensure reliable scanning.

4.7 Legacy encodings (informative)

Earlier drafts described raw JSON or an LCX:-prefixed compressed blob as the full QR contents. Those forms are not LCX 1.0–conformant. New Providers MUST emit the lcx://v1?p=... form only. Consumers are not required to support legacy encodings.


5. Media Assets

This section defines how visual assets (photographs, logos, background images) are referenced and delivered within a Card Payload.

5.1 Media Object Structure

The media object in the Card Payload contains named asset slots:

{
  "media": {
    "profilePhoto": { ... },
    "backgroundImage": { ... },
    "organizationLogo": { ... },
    "customAssets": [ ... ]
  }
}

5.2 Asset Object

Each asset (whether in a named slot or in the customAssets array) is an object with the following fields:

FieldTypeRequiredDescription
urlstring (URL)REQUIREDAbsolute HTTPS URL from which the asset can be fetched.
mimeTypestringREQUIREDThe MIME type of the asset. See Section 5.3 for supported types.
widthintegerRECOMMENDEDThe intrinsic width of the asset in pixels.
heightintegerRECOMMENDEDThe intrinsic height of the asset in pixels.
blurhashstringOPTIONALA BlurHash string for rendering a placeholder while the asset loads.
altstringOPTIONALAccessibility text describing the asset.
datastringOPTIONALBase64-encoded inline data URI (e.g., "data:image/png;base64,...") for offline or snapshot use. See Section 5.5.

5.3 Supported Formats

Card Providers MUST serve assets in at least one of the following formats:

MIME TypeExtensionUsage
image/jpeg.jpg, .jpegPhotographs, background images
image/png.pngLogos, graphics with transparency
image/webp.webpOptimized photographs and graphics
image/svg+xml.svgVector logos and icons

Card Consumers MUST support image/jpeg and image/png. Support for image/webp and image/svg+xml is RECOMMENDED.

5.4 Resolution Guidance

AssetMinimum SizeRecommended SizeMaximum Size
profilePhoto256 x 256 px512 x 512 px2048 x 2048 px
backgroundImage800 x 480 px1600 x 960 px3200 x 1920 px
organizationLogo128 x 128 px256 x 256 px1024 x 1024 px

Providers SHOULD serve assets at or above the recommended size. Consumers SHOULD downscale assets to fit the display rather than upscaling below-minimum assets.

Asset file sizes SHOULD NOT exceed 2 MB per individual asset and 5 MB total across all assets in a single Card Payload.

5.5 Inline Data

Assets MAY include a data field containing a base64-encoded data URI. This is intended for:

  • Providing a low-resolution preview that can be rendered immediately without a network request.
  • Enabling basic offline rendering when the Consumer has never fetched the full-resolution asset.

When a data field is present alongside a url field, Consumers MUST treat the url as the authoritative source and use data only as a fallback or placeholder. Inline data SHOULD be kept small (under 50 KB per asset) to avoid inflating the Card Payload.

5.6 Custom Assets

The customAssets array allows Providers to attach additional images to a card (e.g., product photos, QR codes for other services, award badges). Each entry follows the Asset Object structure (Section 5.2) with an additional field:

FieldTypeRequiredDescription
idstringREQUIREDA unique identifier for this custom asset within the card.
labelstringOPTIONALA human-readable label describing the asset.

Custom assets can be referenced by layout elements using their id (see Section 6).


6. Card Layout and Positioning

This section defines the absolute-positioning layout system that controls how card elements are visually arranged.

6.1 Canvas

All layout positions are defined within a virtual canvas — an abstract coordinate space that is independent of physical screen resolution.

PropertyDefaultDescription
width1000The canvas width in abstract units.
height600The canvas height in abstract units.

The default canvas represents a standard landscape business card with a 5:3 aspect ratio. Providers MAY override the canvas dimensions to support portrait or custom aspect ratios.

{
  "layout": {
    "canvas": {
      "width": 1000,
      "height": 600
    },
    "backgroundColor": "#FFFFFF",
    "elements": [ ... ]
  }
}

Rendering rule: Card Consumers MUST scale the canvas uniformly to fit the available display area while preserving the aspect ratio. The origin (0, 0) is the top-left corner of the canvas. The x-axis increases to the right; the y-axis increases downward.

6.2 Layout Object

The layout object within the Card Payload has the following fields:

FieldTypeRequiredDescription
canvasobjectOPTIONALCanvas dimensions: { "width": <int>, "height": <int> }. Defaults to { "width": 1000, "height": 600 } if omitted.
backgroundColorstring (color)OPTIONALThe card's background color. Defaults to "#FFFFFF".
elementsarrayREQUIRED (if layout is present)An ordered array of layout elements to render on the canvas.

6.3 Layout Elements

Each entry in the elements array is a layout element object that describes a single visual component on the card.

6.3.1 Common Element Fields

These fields apply to all element types:

FieldTypeRequiredDescription
idstringREQUIREDA unique identifier for this element within the card.
typestringREQUIREDThe element type. MUST be one of: "text", "image", "shape", "divider", "qrCode", "icon".
dataBindingstringOPTIONALA dot-notation path to the data field this element displays (e.g., "identity.fullName", "media.profilePhoto", "contacts.0.value"). If present, the element renders the bound data. If absent, the element uses its inline content or src field.
xnumberREQUIREDHorizontal position of the element's top-left corner in canvas units.
ynumberREQUIREDVertical position of the element's top-left corner in canvas units.
widthnumberREQUIREDElement width in canvas units.
heightnumberREQUIREDElement height in canvas units.
zIndexintegerOPTIONALStacking order. Higher values render on top. Defaults to 0. Elements with equal zIndex are rendered in array order.
rotationnumberOPTIONALClockwise rotation in degrees (0–360) around the element's center point. Defaults to 0.
opacitynumberOPTIONALOpacity from 0.0 (fully transparent) to 1.0 (fully opaque). Defaults to 1.0.
visiblebooleanOPTIONALWhether the element is rendered. Defaults to true. Allows Providers to include hidden elements that may be toggled by future features.

6.3.2 Text Elements

For elements with "type": "text":

FieldTypeRequiredDescription
contentstringOPTIONALStatic text content. Ignored if dataBinding is set.
styleobjectOPTIONALText styling properties (see below).

Text style properties:

FieldTypeDefaultDescription
fontFamilystring"sans-serif"The font family name. Consumers SHOULD support common web-safe fonts and MAY support custom fonts via URL.
fontSizenumber24Font size in canvas units.
fontWeightstring or integer"normal"CSS-compatible font weight (e.g., "bold", "normal", 100900).
fontStylestring"normal""normal" or "italic".
colorstring (color)"#000000"Text color.
textAlignstring"left""left", "center", "right", or "justify".
verticalAlignstring"top""top", "middle", or "bottom".
lineHeightnumber1.2Line height as a multiplier of fontSize.
letterSpacingnumber0Additional spacing between characters in canvas units.
textDecorationstring"none""none", "underline", "line-through", or "overline".
textTransformstring"none""none", "uppercase", "lowercase", or "capitalize".
overflowstring"wrap"Behavior when text exceeds the element bounds: "wrap" (default), "ellipsis", or "clip".

6.3.3 Image Elements

For elements with "type": "image":

FieldTypeRequiredDescription
srcstring (URL)OPTIONALDirect URL to the image. Ignored if dataBinding is set (the bound media asset's url is used instead).
styleobjectOPTIONALImage styling properties (see below).

Image style properties:

FieldTypeDefaultDescription
objectFitstring"cover"How the image fits within the element bounds: "cover", "contain", or "fill".
borderRadiusnumber0Corner radius in canvas units. Use a value equal to half the smaller dimension for a circle.
borderobjectnoneBorder specification: { "width": <number>, "color": "<color>", "style": "solid" }.

6.3.4 Shape Elements

For elements with "type": "shape":

FieldTypeRequiredDescription
shapestringREQUIREDThe shape to render: "rectangle", "ellipse", "triangle", or "line".
styleobjectOPTIONALShape styling properties (see below).

Shape style properties:

FieldTypeDefaultDescription
fillColorstring (color)"transparent"Fill color.
strokeColorstring (color)"#000000"Stroke (border) color.
strokeWidthnumber1Stroke width in canvas units.
borderRadiusnumber0Corner radius for rectangles, in canvas units.

6.3.5 Divider Elements

For elements with "type": "divider":

FieldTypeDefaultDescription
style.colorstring (color)"#CCCCCC"Line color.
style.thicknessnumber2Line thickness in canvas units.
style.patternstring"solid""solid", "dashed", or "dotted".

The divider renders as a horizontal line spanning the element's width at the vertical center of its height.

6.3.6 QR Code Elements

For elements with "type": "qrCode":

FieldTypeRequiredDescription
qrDatastringOPTIONALThe data to encode in the on-card QR element. If omitted, Consumers SHOULD encode the LCX QR URI for the card (Section 4.1) so scanning opens an LCX Consumer; alternatively, Consumers MAY encode the Card URI alone if the design intent is a generic HTTPS link without opening a registered lcx app.
styleobjectOPTIONALQR styling properties.

QR Code style properties:

FieldTypeDefaultDescription
foregroundColorstring (color)"#000000"Module (dot) color.
backgroundColorstring (color)"#FFFFFF"Background color.
errorCorrectionstring"M"Error correction level: "L", "M", "Q", or "H".

6.3.7 Icon Elements

For elements with "type": "icon":

FieldTypeRequiredDescription
iconstringREQUIREDIcon identifier. Providers SHOULD use identifiers from a well-known icon set (e.g., Material Icons names like "phone", "email", "location_on"). Alternatively, a URL to an SVG icon.
styleobjectOPTIONALIcon styling properties.

Icon style properties:

FieldTypeDefaultDescription
colorstring (color)"#000000"Icon tint color.

6.4 Default Layout Fallback

If the layout field is absent from the Card Payload, or if the elements array is empty, Card Consumers MUST render a default card layout using the available data fields. The specific design of the default layout is left to the Consumer, but it MUST display at minimum:

  1. The identity.fullName field.
  2. The professional.jobTitle and professional.organization fields, if present.
  3. The first contacts entry of type "email" and "phone", if present.
  4. The media.profilePhoto, if present.

7. Update Server Protocol

This section defines the REST API that Card Providers MUST implement to serve Card Payloads to Card Consumers.

7.1 Base URL

Card Providers choose their own base URL. The LCX protocol path is appended to it:

{baseUrl}/lcx/v1/cards/{cardId}

For example:

https://cards.example.com/lcx/v1/cards/550e8400-e29b-41d4-a716-446655440000

The full URL is the Card URI and is the value stored in the QR Payload's uri field.

7.2 Fetch Card

Request:

GET /lcx/v1/cards/{cardId} HTTP/1.1
Host: cards.example.com
Accept: application/vnd.lcx.card+json, application/json

Successful Response (200 OK):

HTTP/1.1 200 OK
Content-Type: application/vnd.lcx.card+json
ETag: "a1b2c3d4e5"
Last-Modified: Sun, 05 Apr 2026 18:30:00 GMT
Cache-Control: public, max-age=3600

The response body is the full Card Payload JSON as defined in Sections 3–6.

Content-Type: Card Providers SHOULD use application/vnd.lcx.card+json as the response content type. Providers MAY fall back to application/json if the custom media type is not practical for their infrastructure. Consumers MUST accept both.

7.3 Conditional Requests

Providers SHOULD support conditional requests to minimize bandwidth:

If-None-Match (ETag-based):

GET /lcx/v1/cards/{cardId} HTTP/1.1
Host: cards.example.com
Accept: application/vnd.lcx.card+json, application/json
If-None-Match: "a1b2c3d4e5"

If the card has not changed, the Provider responds:

HTTP/1.1 304 Not Modified
ETag: "a1b2c3d4e5"
Cache-Control: public, max-age=3600

If-Modified-Since (Date-based):

GET /lcx/v1/cards/{cardId} HTTP/1.1
Host: cards.example.com
Accept: application/vnd.lcx.card+json, application/json
If-Modified-Since: Sun, 05 Apr 2026 18:30:00 GMT

Providers SHOULD support at least ETag/If-None-Match. Support for If-Modified-Since is RECOMMENDED.

7.4 Error Responses

All error responses MUST use standard HTTP status codes and SHOULD include a JSON body:

{
  "error": {
    "code": "<error_code>",
    "message": "<human_readable_message>"
  }
}
Status CodeError CodeDescription
400bad_requestMalformed request.
401unauthorizedAuthentication is required but was not provided or is invalid.
403forbiddenThe provided credentials do not have access to this card.
404not_foundThe card does not exist or the Card ID is invalid.
410goneThe card has been permanently deleted. Consumers SHOULD remove this card from their local storage and inform the user.
429rate_limitedToo many requests. The response MUST include a Retry-After header (in seconds).
500internal_errorServer-side error.

7.5 CORS

Card Providers that intend to support browser-based Card Consumers SHOULD include appropriate CORS headers:

Access-Control-Allow-Origin: *
Access-Control-Allow-Methods: GET, OPTIONS
Access-Control-Allow-Headers: Authorization, Accept, If-None-Match, If-Modified-Since
Access-Control-Expose-Headers: ETag, Last-Modified, Retry-After

7.6 Rate Limiting

Card Providers SHOULD implement rate limiting to protect against abuse. When a Consumer is rate limited:

  1. The Provider MUST respond with 429 Too Many Requests.
  2. The response MUST include a Retry-After header indicating the number of seconds before the Consumer may retry.
  3. Consumers MUST respect the Retry-After value and MUST NOT retry before it expires.

Providers SHOULD allow at least 60 requests per minute per Card ID per client IP for public cards.


8. Authentication

LCX supports optional authentication for cards that should not be publicly accessible.

8.1 Authentication Methods

Methodauth ValueDescription
None (Public)"none"No authentication required. This is the default.
Bearer Token"bearer"Consumer includes a token in the Authorization header.
Query Parameter"query"Consumer includes a token as a URL query parameter.

8.2 Public Cards

When auth is "none" (or omitted), the Card is publicly accessible. Consumers send a standard GET request with no authentication headers.

8.3 Bearer Token Authentication

When auth is "bearer":

  1. The QR Payload MUST include a token field containing the bearer token.
  2. The Consumer MUST include the token in the HTTP Authorization header when fetching the card:
GET /lcx/v1/cards/{cardId} HTTP/1.1
Host: cards.example.com
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
Accept: application/vnd.lcx.card+json, application/json
  1. If the token is missing, expired, or invalid, the Provider MUST respond with 401 Unauthorized.

8.4 Query Parameter Authentication

When auth is "query":

  1. The QR Payload MUST include a token field containing the token value.
  2. The Consumer MUST append the token as a query parameter when fetching the card:
GET /lcx/v1/cards/{cardId}?token=abc123def456 HTTP/1.1
Host: cards.example.com
Accept: application/vnd.lcx.card+json, application/json
  1. This method is provided for simpler integrations where modifying HTTP headers is impractical. Bearer token authentication (Section 8.3) is RECOMMENDED over query parameter authentication when possible.

8.5 Token Provisioning

How tokens are generated, rotated, and revoked is outside the scope of LCX 1.0. Card Providers are free to use any mechanism (JWTs, opaque tokens, API keys, etc.). The standard only defines how tokens are carried in QR Payloads and HTTP requests.

8.6 Token Storage

Card Consumers that receive authenticated cards MUST store the associated token alongside the cached Card Payload. Consumers SHOULD store tokens using platform-appropriate secure storage mechanisms (e.g., Keychain on iOS, EncryptedSharedPreferences on Android).


9. Caching and Offline Behavior

A core benefit of LCX is that cards update live. However, Consumers must also function when the Card Provider is unreachable.

9.1 Client-Side Caching Requirements

  1. Card Payload caching: Consumers MUST cache the most recently fetched Card Payload for each card in persistent local storage. The cached payload MUST survive app restarts.
  2. Media asset caching: Consumers SHOULD cache fetched media assets (images) separately from the Card Payload, keyed by their URL. Asset caches SHOULD persist across app restarts.
  3. Token caching: Consumers MUST persist authentication tokens for authenticated cards (see Section 8.6).

9.2 Refresh Behavior

  1. Consumers SHOULD attempt to refresh a card from the Update Endpoint when:
    • The card is opened or viewed by the user.
    • The time since the last successful fetch exceeds the card's ttl value.
    • The user manually triggers a refresh.
  2. Consumers SHOULD NOT fetch more frequently than the card's ttl value unless the user explicitly requests a refresh.
  3. Consumers SHOULD use conditional requests (Section 7.3) to minimize bandwidth.

9.3 Offline Fallback

When the Update Endpoint is unreachable (network error, timeout, DNS failure):

  1. Consumers MUST display the cached Card Payload.
  2. Consumers MUST provide a visual indicator that the displayed data may be stale (e.g., a "Last updated" timestamp, a subtle banner, or an icon).
  3. Consumers SHOULD retry the fetch according to an exponential backoff strategy, respecting the card's ttl as the minimum interval.

9.4 Card Deletion

When a Provider returns 410 Gone:

  1. Consumers SHOULD mark the card as deleted in local storage.
  2. Consumers SHOULD inform the user that the card has been permanently removed by its owner.
  3. Consumers MAY retain the cached data for a grace period (e.g., 30 days) to allow the user to note down any information they need before the card is purged.

10. Security Considerations

10.1 Transport Security

All Update Endpoint URLs MUST use HTTPS with TLS 1.2 or higher. Card Consumers MUST reject Update Endpoint URLs that use plain HTTP. Card Consumers MUST validate the server's TLS certificate against the platform's trusted certificate store.

10.2 QR Code Integrity

QR codes are inherently susceptible to tampering (e.g., a malicious QR code sticker placed over a legitimate one). LCX 1.0 does not define a cryptographic signature mechanism for QR Payloads. Consumers SHOULD:

  1. Display the Update Endpoint domain prominently when a card is first scanned, so the user can verify it comes from an expected source.
  2. Warn the user if the domain is an IP address or uses an unusual TLD.

Future versions of LCX MAY introduce payload signing to mitigate this risk.

10.3 Token Security

  1. Tokens MUST be transmitted only over HTTPS.
  2. Consumers MUST NOT log tokens in plaintext.
  3. Consumers MUST store tokens in platform-secure storage (see Section 8.6).
  4. Providers SHOULD issue tokens with limited scope (per-card access only) and SHOULD support token revocation.

10.4 Rate Limiting and Abuse Prevention

Card Providers SHOULD implement rate limiting (see Section 7.6) to prevent:

  • Enumeration attacks (sequentially guessing Card IDs).
  • Denial-of-service attacks against the Update Endpoint.

Card IDs are UUID v4 (122 bits of randomness), making enumeration impractical, but rate limiting provides defense in depth.

10.5 Data Privacy

  1. Card Providers MUST support card deletion and MUST return 410 Gone for deleted cards, enabling Consumers to remove personal data.
  2. Card Providers SHOULD provide card owners with the ability to see which data is published in their card.
  3. Card Consumers SHOULD allow users to delete any stored card and its associated data from local storage at any time.
  4. Implementers in jurisdictions subject to GDPR, POPIA, CCPA, or similar regulations MUST ensure their implementations comply with applicable data protection requirements.

11. Extensibility and Versioning

11.1 Version Identification

Every Card Payload includes an lcxVersion field (Section 3.2) and every QR Payload includes an lcx field (Section 4.3). These fields allow Consumers to determine which version of the standard the data conforms to.

11.2 Forward Compatibility

To ensure forward compatibility:

  1. Consumers MUST ignore unknown fields. If a Card Payload or QR Payload contains fields not defined in the version of the standard that the Consumer implements, those fields MUST be silently ignored. Consumers MUST NOT treat unknown fields as an error.
  2. Consumers MUST ignore unknown element types. If a layout element has a type not recognized by the Consumer, the element MUST be skipped during rendering.
  3. Consumers MUST preserve unknown fields when caching. If a Consumer caches a Card Payload containing fields it does not recognize, those fields MUST be retained in the cache so they are available if the Consumer is later updated to a version that supports them.

11.3 Versioning Policy

  • Patch versions (e.g., 1.0.1): Clarifications and errata only. No new fields, no behavioral changes.
  • Minor versions (e.g., 1.1): New OPTIONAL fields, new element types, new authentication methods. Fully backward-compatible with the same major version. A Consumer implementing LCX 1.0 can read a 1.1 payload (ignoring new fields).
  • Major versions (e.g., 2.0): Breaking changes to required fields, payload structure, or protocol behavior. Consumers MUST check the lcxVersion / lcx field and inform the user if they encounter a major version they do not support.

11.4 Extension Namespace

Providers MAY include custom extension fields in the Card Payload by prefixing them with x-. For example:

{
  "lcxVersion": "1.0",
  "cardId": "...",
  "x-myplatform-theme": "dark",
  "x-myplatform-animationEnabled": true,
  ...
}

Extension fields MUST NOT override or conflict with standard fields. Consumers MUST ignore extension fields they do not recognize (per Section 11.2).


Appendix A: JSON Schema

The following JSON Schema (draft 2020-12) defines the structure of an LCX 1.0 Card Payload. The canonical machine-readable schema is available at schemas/card-payload.schema.json.

{
  "$schema": "https://json-schema.org/draft/2020-12/schema",
  "$id": "https://lcx.componera.com/schemas/card-payload/1.0",
  "title": "LCX Card Payload",
  "description": "A LiveCard Exchange (LCX) 1.0 business card payload.",
  "type": "object",
  "required": ["lcxVersion", "cardId", "createdAt", "updatedAt", "identity"],
  "properties": {
    "lcxVersion": {
      "type": "string",
      "const": "1.0",
      "description": "LCX specification version."
    },
    "cardId": {
      "type": "string",
      "format": "uuid",
      "description": "Globally unique card identifier (UUID v4)."
    },
    "createdAt": {
      "type": "string",
      "format": "date-time",
      "description": "ISO 8601 creation timestamp."
    },
    "updatedAt": {
      "type": "string",
      "format": "date-time",
      "description": "ISO 8601 last-modified timestamp."
    },
    "ttl": {
      "type": "integer",
      "minimum": 0,
      "description": "Suggested re-fetch interval in seconds."
    },
    "identity": {
      "type": "object",
      "required": ["fullName"],
      "properties": {
        "fullName": { "type": "string" },
        "preferredName": { "type": "string" },
        "prefix": { "type": "string" },
        "suffix": { "type": "string" },
        "pronouns": { "type": "string" }
      },
      "additionalProperties": false
    },
    "professional": {
      "type": "object",
      "properties": {
        "jobTitle": { "type": "string" },
        "department": { "type": "string" },
        "organization": { "type": "string" },
        "organizationUrl": { "type": "string", "format": "uri" }
      },
      "additionalProperties": false
    },
    "contacts": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["type", "value"],
        "properties": {
          "type": {
            "type": "string",
            "enum": ["phone", "email", "fax", "pager", "sms", "whatsapp", "telegram", "signal", "other"]
          },
          "value": { "type": "string" },
          "label": { "type": "string" },
          "preferred": { "type": "boolean", "default": false }
        },
        "additionalProperties": false
      }
    },
    "addresses": {
      "type": "array",
      "items": {
        "type": "object",
        "properties": {
          "label": { "type": "string" },
          "street": { "type": "string" },
          "city": { "type": "string" },
          "state": { "type": "string" },
          "postalCode": { "type": "string" },
          "country": { "type": "string" },
          "coordinates": {
            "type": "object",
            "properties": {
              "lat": { "type": "number" },
              "lng": { "type": "number" }
            },
            "required": ["lat", "lng"],
            "additionalProperties": false
          }
        },
        "additionalProperties": false
      }
    },
    "socials": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["platform", "url"],
        "properties": {
          "platform": { "type": "string" },
          "url": { "type": "string", "format": "uri" },
          "handle": { "type": "string" }
        },
        "additionalProperties": false
      }
    },
    "customFields": {
      "type": "array",
      "items": {
        "type": "object",
        "required": ["label", "value"],
        "properties": {
          "label": { "type": "string" },
          "value": { "type": "string" },
          "icon": { "type": "string", "format": "uri" }
        },
        "additionalProperties": false
      }
    },
    "bio": {
      "type": "string"
    },
    "media": {
      "type": "object",
      "properties": {
        "profilePhoto": { "$ref": "#/$defs/asset" },
        "backgroundImage": { "$ref": "#/$defs/asset" },
        "organizationLogo": { "$ref": "#/$defs/asset" },
        "customAssets": {
          "type": "array",
          "items": {
            "allOf": [
              { "$ref": "#/$defs/asset" },
              {
                "type": "object",
                "required": ["id"],
                "properties": {
                  "id": { "type": "string" },
                  "label": { "type": "string" }
                }
              }
            ]
          }
        }
      },
      "additionalProperties": false
    },
    "layout": {
      "type": "object",
      "properties": {
        "canvas": {
          "type": "object",
          "properties": {
            "width": { "type": "integer", "default": 1000 },
            "height": { "type": "integer", "default": 600 }
          },
          "additionalProperties": false
        },
        "backgroundColor": { "type": "string" },
        "elements": {
          "type": "array",
          "items": { "$ref": "#/$defs/layoutElement" }
        }
      },
      "additionalProperties": false
    }
  },
  "additionalProperties": true,
  "$defs": {
    "asset": {
      "type": "object",
      "required": ["url", "mimeType"],
      "properties": {
        "url": { "type": "string", "format": "uri" },
        "mimeType": { "type": "string" },
        "width": { "type": "integer" },
        "height": { "type": "integer" },
        "blurhash": { "type": "string" },
        "alt": { "type": "string" },
        "data": { "type": "string" }
      },
      "additionalProperties": false
    },
    "layoutElement": {
      "type": "object",
      "required": ["id", "type", "x", "y", "width", "height"],
      "properties": {
        "id": { "type": "string" },
        "type": {
          "type": "string",
          "enum": ["text", "image", "shape", "divider", "qrCode", "icon"]
        },
        "dataBinding": { "type": "string" },
        "x": { "type": "number" },
        "y": { "type": "number" },
        "width": { "type": "number" },
        "height": { "type": "number" },
        "zIndex": { "type": "integer", "default": 0 },
        "rotation": { "type": "number", "default": 0 },
        "opacity": { "type": "number", "minimum": 0, "maximum": 1, "default": 1.0 },
        "visible": { "type": "boolean", "default": true },
        "content": { "type": "string" },
        "src": { "type": "string", "format": "uri" },
        "shape": {
          "type": "string",
          "enum": ["rectangle", "ellipse", "triangle", "line"]
        },
        "qrData": { "type": "string" },
        "icon": { "type": "string" },
        "style": { "type": "object" }
      },
      "additionalProperties": true
    }
  }
}

Appendix B: Example Card Payload

The following is a complete example of an LCX 1.0 Card Payload:

{
  "lcxVersion": "1.0",
  "cardId": "550e8400-e29b-41d4-a716-446655440000",
  "createdAt": "2026-03-15T09:00:00Z",
  "updatedAt": "2026-04-05T18:30:00Z",
  "ttl": 3600,
  "identity": {
    "fullName": "Jane Smith",
    "preferredName": "Jane",
    "prefix": "Ms.",
    "pronouns": "she/her"
  },
  "professional": {
    "jobTitle": "Chief Technology Officer",
    "department": "Engineering",
    "organization": "Componera (PTY) LTD",
    "organizationUrl": "https://componera.com"
  },
  "contacts": [
    {
      "type": "email",
      "value": "[email protected]",
      "label": "Work",
      "preferred": true
    },
    {
      "type": "phone",
      "value": "+27821234567",
      "label": "Mobile",
      "preferred": true
    },
    {
      "type": "phone",
      "value": "+27111234567",
      "label": "Office"
    }
  ],
  "addresses": [
    {
      "label": "Head Office",
      "street": "42 Innovation Drive, Tech Park",
      "city": "Johannesburg",
      "state": "Gauteng",
      "postalCode": "2000",
      "country": "ZA",
      "coordinates": {
        "lat": -26.2041,
        "lng": 28.0473
      }
    }
  ],
  "socials": [
    {
      "platform": "linkedin",
      "url": "https://linkedin.com/in/janesmith",
      "handle": "janesmith"
    },
    {
      "platform": "github",
      "url": "https://github.com/janesmith",
      "handle": "janesmith"
    },
    {
      "platform": "x",
      "url": "https://x.com/janesmith",
      "handle": "@janesmith"
    }
  ],
  "customFields": [
    {
      "label": "Languages",
      "value": "English, Afrikaans, Zulu"
    }
  ],
  "bio": "Passionate technologist with 15 years of experience building scalable systems. Leading the engineering team at Componera to redefine how professionals connect.",
  "media": {
    "profilePhoto": {
      "url": "https://cards.componera.com/assets/550e8400/profile.jpg",
      "mimeType": "image/jpeg",
      "width": 512,
      "height": 512,
      "blurhash": "LEHV6nWB2yk8pyo0adR*.7kCMdnj",
      "alt": "Jane Smith headshot"
    },
    "backgroundImage": {
      "url": "https://cards.componera.com/assets/550e8400/background.jpg",
      "mimeType": "image/jpeg",
      "width": 1600,
      "height": 960,
      "blurhash": "LGF5]+Yk^6#M@-5c,1J5@[or[Q6.",
      "alt": "Abstract blue gradient background"
    },
    "organizationLogo": {
      "url": "https://cards.componera.com/assets/550e8400/logo.svg",
      "mimeType": "image/svg+xml",
      "width": 256,
      "height": 256,
      "alt": "Componera logo"
    }
  },
  "layout": {
    "canvas": {
      "width": 1000,
      "height": 600
    },
    "backgroundColor": "#1A1A2E",
    "elements": [
      {
        "id": "bg",
        "type": "image",
        "dataBinding": "media.backgroundImage",
        "x": 0,
        "y": 0,
        "width": 1000,
        "height": 600,
        "zIndex": 0,
        "style": {
          "objectFit": "cover",
          "opacity": 0.3
        }
      },
      {
        "id": "photo",
        "type": "image",
        "dataBinding": "media.profilePhoto",
        "x": 60,
        "y": 120,
        "width": 200,
        "height": 200,
        "zIndex": 2,
        "style": {
          "objectFit": "cover",
          "borderRadius": 100,
          "border": {
            "width": 3,
            "color": "#FFFFFF",
            "style": "solid"
          }
        }
      },
      {
        "id": "name",
        "type": "text",
        "dataBinding": "identity.fullName",
        "x": 300,
        "y": 130,
        "width": 450,
        "height": 60,
        "zIndex": 2,
        "style": {
          "fontFamily": "sans-serif",
          "fontSize": 42,
          "fontWeight": "bold",
          "color": "#FFFFFF",
          "textAlign": "left"
        }
      },
      {
        "id": "title",
        "type": "text",
        "dataBinding": "professional.jobTitle",
        "x": 300,
        "y": 195,
        "width": 450,
        "height": 35,
        "zIndex": 2,
        "style": {
          "fontFamily": "sans-serif",
          "fontSize": 22,
          "fontWeight": "normal",
          "color": "#E0E0E0",
          "textAlign": "left"
        }
      },
      {
        "id": "org",
        "type": "text",
        "dataBinding": "professional.organization",
        "x": 300,
        "y": 235,
        "width": 450,
        "height": 30,
        "zIndex": 2,
        "style": {
          "fontFamily": "sans-serif",
          "fontSize": 18,
          "fontWeight": "normal",
          "color": "#B0B0B0",
          "textAlign": "left"
        }
      },
      {
        "id": "divider1",
        "type": "divider",
        "x": 300,
        "y": 280,
        "width": 450,
        "height": 10,
        "zIndex": 2,
        "style": {
          "color": "rgba(255, 255, 255, 0.3)",
          "thickness": 1,
          "pattern": "solid"
        }
      },
      {
        "id": "emailIcon",
        "type": "icon",
        "icon": "email",
        "x": 300,
        "y": 305,
        "width": 24,
        "height": 24,
        "zIndex": 2,
        "style": {
          "color": "#FFFFFF"
        }
      },
      {
        "id": "emailText",
        "type": "text",
        "dataBinding": "contacts.0.value",
        "x": 335,
        "y": 303,
        "width": 400,
        "height": 28,
        "zIndex": 2,
        "style": {
          "fontFamily": "sans-serif",
          "fontSize": 16,
          "color": "#FFFFFF",
          "textAlign": "left"
        }
      },
      {
        "id": "phoneIcon",
        "type": "icon",
        "icon": "phone",
        "x": 300,
        "y": 345,
        "width": 24,
        "height": 24,
        "zIndex": 2,
        "style": {
          "color": "#FFFFFF"
        }
      },
      {
        "id": "phoneText",
        "type": "text",
        "dataBinding": "contacts.1.value",
        "x": 335,
        "y": 343,
        "width": 400,
        "height": 28,
        "zIndex": 2,
        "style": {
          "fontFamily": "sans-serif",
          "fontSize": 16,
          "color": "#FFFFFF",
          "textAlign": "left"
        }
      },
      {
        "id": "logo",
        "type": "image",
        "dataBinding": "media.organizationLogo",
        "x": 850,
        "y": 30,
        "width": 100,
        "height": 100,
        "zIndex": 2,
        "style": {
          "objectFit": "contain"
        }
      },
      {
        "id": "qr",
        "type": "qrCode",
        "x": 830,
        "y": 420,
        "width": 140,
        "height": 140,
        "zIndex": 2,
        "style": {
          "foregroundColor": "#FFFFFF",
          "backgroundColor": "transparent",
          "errorCorrection": "M"
        }
      }
    ]
  }
}

Appendix C: Example QR Code Payload

The strings below are decoded QR Payloads (JSON). A conformant share QR encodes lcx://v1?p=<base64url(JSON)>, as in Section 4.1.

C.1 Minimal QR Payload (Public Card)

Decoded QR Payload:

{"lcx":"1","uri":"https://cards.componera.com/lcx/v1/cards/550e8400-e29b-41d4-a716-446655440000","cid":"550e8400-e29b-41d4-a716-446655440000"}

Example LCX QR URI (full QR contents):

lcx://v1?p=eyJsY3giOiIxIiwidXJpIjoiaHR0cHM6Ly9jYXJkcy5jb21wb25lcmEuY29tL2xjeC92MS9jYXJkcy81NTBlODQwMC1lMjliLTQxZDQtYTcxNi00NDY2NTU0NDAwMDAiLCJjaWQiOiI1NTBlODQwMC1lMjliLTQxZDQtYTcxNi00NDY2NTU0NDAwMDAifQ

C.2 QR Payload with Snapshot

Decoded QR Payload:

{
  "lcx": "1",
  "uri": "https://cards.componera.com/lcx/v1/cards/550e8400-e29b-41d4-a716-446655440000",
  "cid": "550e8400-e29b-41d4-a716-446655440000",
  "auth": "none",
  "snapshot": {
    "fn": "Jane Smith",
    "title": "Chief Technology Officer",
    "org": "Componera (PTY) LTD",
    "email": "[email protected]",
    "phone": "+27821234567"
  }
}

Example LCX QR URI (full QR contents):

lcx://v1?p=eyJsY3giOiIxIiwidXJpIjoiaHR0cHM6Ly9jYXJkcy5jb21wb25lcmEuY29tL2xjeC92MS9jYXJkcy81NTBlODQwMC1lMjliLTQxZDQtYTcxNi00NDY2NTU0NDAwMDAiLCJjaWQiOiI1NTBlODQwMC1lMjliLTQxZDQtYTcxNi00NDY2NTU0NDAwMDAiLCJhdXRoIjoibm9uZSIsInNuYXBzaG90Ijp7ImZuIjoiSmFuZSBTbWl0aCIsInRpdGxlIjoiQ2hpZWYgVGVjaG5vbG9neSBPZmZpY2VyIiwib3JnIjoiQ29tcG9uZXJhIChQVFkpIExURCIsImVtYWlsIjoiamFuZUBjb21wb25lcmEuY29tIiwicGhvbmUiOiIrMjc4MjEyMzQ1NjcifX0

C.3 QR Payload with Bearer Authentication

Decoded QR Payload:

{
  "lcx": "1",
  "uri": "https://cards.componera.com/lcx/v1/cards/7a3b9c12-d4e5-6f78-90ab-cdef12345678",
  "cid": "7a3b9c12-d4e5-6f78-90ab-cdef12345678",
  "auth": "bearer",
  "token": "eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJjYXJkSWQiOiI3YTNiOWMxMi1kNGU1LTZmNzgtOTBhYi1jZGVmMTIzNDU2NzgiLCJleHAiOjE3NTYwMDAwMDB9.signature",
  "snapshot": {
    "fn": "John Doe",
    "title": "Managing Director",
    "org": "Acme Corp"
  }
}

Example LCX QR URI (full QR contents):

lcx://v1?p=eyJsY3giOiIxIiwidXJpIjoiaHR0cHM6Ly9jYXJkcy5jb21wb25lcmEuY29tL2xjeC92MS9jYXJkcy83YTNiOWMxMi1kNGU1LTZmNzgtOTBhYi1jZGVmMTIzNDU2NzgiLCJjaWQiOiI3YTNiOWMxMi1kNGU1LTZmNzgtOTBhYi1jZGVmMTIzNDU2NzgiLCJhdXRoIjoiYmVhcmVyIiwidG9rZW4iOiJleUpoYkdjaU9pSklVekkxTmlJc0luUjVjQ0k2SWtwWFZDSjkuZXlKallYSmtTV1FpT2lJM1lUTmlPV014TWkxa05HVTFMVFptTnpndE9UQmhZaTFqWkdWbU1USXpORFUyTnpnaUxDSmxlSEFpT2pFM05UWXdNREF3TURCOS5zaWduYXR1cmUiLCJzbmFwc2hvdCI6eyJmbiI6IkpvaG4gRG9lIiwidGl0bGUiOiJNYW5hZ2luZyBEaXJlY3RvciIsIm9yZyI6IkFjbWUgQ29ycCJ9fQ

Appendix D: Example HTTP Exchange

D.1 Initial Fetch

Request:

GET /lcx/v1/cards/550e8400-e29b-41d4-a716-446655440000 HTTP/1.1
Host: cards.componera.com
Accept: application/vnd.lcx.card+json, application/json
User-Agent: LiveRolodex/1.0 (LCX-Consumer)

Response:

HTTP/1.1 200 OK
Content-Type: application/vnd.lcx.card+json
ETag: "v42-2026040518"
Last-Modified: Sun, 05 Apr 2026 18:30:00 GMT
Cache-Control: public, max-age=3600

{
  "lcxVersion": "1.0",
  "cardId": "550e8400-e29b-41d4-a716-446655440000",
  "createdAt": "2026-03-15T09:00:00Z",
  "updatedAt": "2026-04-05T18:30:00Z",
  "ttl": 3600,
  "identity": {
    "fullName": "Jane Smith"
  },
  ...
}

D.2 Conditional Fetch (Not Modified)

Request:

GET /lcx/v1/cards/550e8400-e29b-41d4-a716-446655440000 HTTP/1.1
Host: cards.componera.com
Accept: application/vnd.lcx.card+json, application/json
If-None-Match: "v42-2026040518"
User-Agent: LiveRolodex/1.0 (LCX-Consumer)

Response:

HTTP/1.1 304 Not Modified
ETag: "v42-2026040518"
Cache-Control: public, max-age=3600

D.3 Conditional Fetch (Modified)

Request:

GET /lcx/v1/cards/550e8400-e29b-41d4-a716-446655440000 HTTP/1.1
Host: cards.componera.com
Accept: application/vnd.lcx.card+json, application/json
If-None-Match: "v42-2026040518"
User-Agent: LiveRolodex/1.0 (LCX-Consumer)

Response:

HTTP/1.1 200 OK
Content-Type: application/vnd.lcx.card+json
ETag: "v43-2026040612"
Last-Modified: Mon, 06 Apr 2026 12:00:00 GMT
Cache-Control: public, max-age=3600

{
  "lcxVersion": "1.0",
  "cardId": "550e8400-e29b-41d4-a716-446655440000",
  "updatedAt": "2026-04-06T12:00:00Z",
  "ttl": 3600,
  "identity": {
    "fullName": "Jane Smith-Williams"
  },
  "professional": {
    "jobTitle": "Co-CEO",
    "organization": "Componera (PTY) LTD"
  },
  ...
}

D.4 Authenticated Fetch

Request:

GET /lcx/v1/cards/7a3b9c12-d4e5-6f78-90ab-cdef12345678 HTTP/1.1
Host: cards.componera.com
Accept: application/vnd.lcx.card+json, application/json
Authorization: Bearer eyJhbGciOiJIUzI1NiIs...
User-Agent: LiveRolodex/1.0 (LCX-Consumer)

Response:

HTTP/1.1 200 OK
Content-Type: application/vnd.lcx.card+json
ETag: "v1-2026040100"
Cache-Control: private, max-age=1800

{
  "lcxVersion": "1.0",
  "cardId": "7a3b9c12-d4e5-6f78-90ab-cdef12345678",
  ...
}

D.5 Card Deleted

Request:

GET /lcx/v1/cards/550e8400-e29b-41d4-a716-446655440000 HTTP/1.1
Host: cards.componera.com
Accept: application/vnd.lcx.card+json, application/json

Response:

HTTP/1.1 410 Gone
Content-Type: application/json

{
  "error": {
    "code": "gone",
    "message": "This card has been permanently deleted by its owner."
  }
}

D.6 Rate Limited

Request:

GET /lcx/v1/cards/550e8400-e29b-41d4-a716-446655440000 HTTP/1.1
Host: cards.componera.com
Accept: application/vnd.lcx.card+json, application/json

Response:

HTTP/1.1 429 Too Many Requests
Content-Type: application/json
Retry-After: 60

{
  "error": {
    "code": "rate_limited",
    "message": "Too many requests. Please retry after 60 seconds."
  }
}

Appendix E: MIME Type Registration

E.1 Media Type

LCX defines a vendor-specific media type for Card Payloads:

  • Type name: application
  • Subtype name: vnd.lcx.card+json
  • Required parameters: None
  • Optional parameters: version (e.g., application/vnd.lcx.card+json; version=1.0)
  • Encoding considerations: UTF-8
  • Published specification: This document (LCX 1.0)
  • Contact: Componera (PTY) LTD

E.2 File Extension

The RECOMMENDED file extension for LCX Card Payload files is .lcx.json.

E.3 Registration Status

As of LCX 1.0, this media type has not been formally registered with IANA. Card Providers and Consumers SHOULD use this media type in anticipation of future registration. Implementations MUST also accept application/json as a fallback.


LCX (LiveCard Exchange) Standard v1.0 -- Copyright 2026 Componera (PTY) LTD. All rights reserved.