Skip to content

Python SDK

Installation (Coming Soon)

Terminal window
pip install xqr-python

Requires Python 3.10+.

Quick Start

import asyncio
from xqr import AsyncXQR
async def main():
xqr = AsyncXQR(api_key="xqr_pk_...")
link = await xqr.links.create(
url="https://example.com",
custom_slug="my-link",
labels=["campaign"],
)
print(link.short_url) # https://xqr.co/my-link
asyncio.run(main())
# Create with routing rules
link = await xqr.links.create(
url="https://example.com/default",
custom_slug="global-promo",
labels=["promo", "q1"],
routing_rules=[
{
"destination": "https://example.de/promo",
"priority": 1,
"conditions": {
"countries": ["DE", "AT", "CH"],
"country_mode": "include",
},
}
],
expires_at="2026-09-30T23:59:59Z",
)
# List with auto-pagination
async for link in xqr.links.list(label="campaign"):
print(f"{link.short_code}: {link.scan_count} scans")
# Update
await xqr.links.update(link.id, url="https://example.com/updated")
# Delete
await xqr.links.delete(link.id)
# Bulk create
result = await xqr.links.bulk_create([
{"url": "https://example.com/page-1"},
{"url": "https://example.com/page-2", "custom_slug": "page-2"},
])
print(f"Created: {len(result.created)}, Errors: {len(result.errors)}")

QR Codes

# Generate a QR code
qr_bytes = await xqr.qr.generate(
content="https://example.com",
format="png",
size=20,
error_correction="H",
foreground="#8B5CF6",
)
with open("qr.png", "wb") as f:
f.write(qr_bytes)
# Create a template
template = await xqr.qr.templates.create(
name="Brand Primary",
design={
"foreground": "#8B5CF6",
"background": "#FFFFFF",
"error_correction": "H",
"logo_url": "https://cdn.xqr.co/logo.png",
"dot_style": "rounded",
},
)
# Render with template
branded = await xqr.qr.templates.render(
template.id,
content="https://example.com/campaign",
size=30,
)

Analytics

# Workspace summary
summary = await xqr.analytics.summary(period="30d")
print(f"Total scans: {summary.total_scans}")
print(f"Growth: {summary.scans_change_pct}%")
# Timeseries
timeseries = await xqr.analytics.timeseries(period="7d", granularity="hour")
for point in timeseries:
print(f"{point.timestamp}: {point.scans}")
# Geography
geo = await xqr.analytics.geography(period="30d")
for g in geo:
print(f"{g.country}: {g.percentage}%")
# Link-specific stats
stats = await xqr.analytics.link_stats(link.id, period="90d")
print(f"{stats.total_scans} scans, {stats.unique_visitors} unique")
# Top links
top = await xqr.analytics.top_links(period="30d", limit=5)
# Create a page
page = await xqr.bio.create(
title="Jane Doe",
slug="janedoe",
bio="Designer & Developer",
links=[
{"title": "Portfolio", "url": "https://janedoe.com"},
{"title": "GitHub", "url": "https://github.com/janedoe", "icon": "github"},
],
)
# Publish
await xqr.bio.publish(page.id)
# Update
await xqr.bio.update(page.id, bio="Senior Designer & Developer")
# Get stats
stats = await xqr.bio.stats(page.id)
print(f"Page views: {stats.page_views}")

Assets

# Upload a file
asset = await xqr.assets.upload("./logo.png")
# Publish to CDN
published = await xqr.assets.publish(asset.id)
print(published.public_url)
# List assets
async for asset in xqr.assets.list():
print(f"{asset.filename} ({asset.status})")

Error Handling

from xqr import AsyncXQR, XQRError, RateLimitError, ValidationError
try:
link = await xqr.links.create(url="invalid")
except ValidationError as e:
print(f"Bad input: {e.message}")
except RateLimitError as e:
print(f"Rate limited. Retry after {e.retry_after}s")
except XQRError as e:
print(f"API error {e.code}: {e.message}")
print(f"Request ID: {e.request_id}")

Configuration

xqr = AsyncXQR(
api_key="xqr_pk_...",
# Optional
base_url="https://xqr.co/api/v1",
timeout=30.0,
max_retries=3,
debug=False,
)
# Or from environment variable
import os
xqr = AsyncXQR(api_key=os.environ["XQR_API_KEY"])

Pydantic Models

All response objects are Pydantic models with full type annotations:

from xqr.models import Link, QRTemplate, BioPage
link: Link = await xqr.links.get("link-id")
print(link.model_dump_json(indent=2))
# Type-safe access
print(link.short_url) # str
print(link.scan_count) # int
print(link.labels) # list[str]
print(link.created_at) # datetime

Stay Updated

Watch the GitHub repository for the SDK release announcement, or subscribe to the changelog RSS feed.

Was this page helpful?