Links
Links are the core resource. A link has a type (website, vCard, WiFi, etc.), a data payload describing its content, optional configuration (custom slug, scheduling, scan limits, password), and an auto-generated QR code.
All endpoints below require an API key with the scope noted on each one.
List links
GET /links
Scope: links.read
Query parameters
| Param | Type | Default | Description |
|---|---|---|---|
page | number | 1 | Page number (1-based). |
size | number | 20 | Items per page (max 1000). |
search | string | — | Case-insensitive match on link name. |
folder | string | — | Filter by folder id. |
qr_type | string | — | Comma-separated list of types, e.g. website,vcard. |
status | string | — | Comma-separated list of statuses. |
only_favorites | boolean | — | When set, returns only favorited links. |
sort_by | string | — | One of most_recent, name, last_modified, most_visited. |
Example
curl "https://api.prolinksqr.com/links?page=1&size=20&sort_by=most_recent" \
-H "Authorization: Basic key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Response 200
{
"data": [
{
"dynamic_link_id": "summer-sale",
"full_dynamic_url": "https://qr-lb.co/summer-sale",
"name": "Summer Sale",
"type": "website",
"meta_data": { "url": "https://example.com/sale" },
"qr_options": { "data": "https://qr-lb.co/summer-sale", "width": 300, "height": 300 },
"folder_id": null,
"created_at": "Jun 24, 2026",
"updated_at": "Jun 24, 2026"
}
],
"meta": { "currentPage": 1, "totalPages": 4 }
}
Get a link
GET /links/:id
Scope: links.read
:id is the link's dynamic_link_id (its slug).
curl https://api.prolinksqr.com/links/summer-sale \
-H "Authorization: Basic key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Response 200
{
"data": {
"dynamic_link_id": "summer-sale",
"full_dynamic_url": "https://qr-lb.co/summer-sale",
"name": "Summer Sale",
"type": "website",
"meta_data": { "url": "https://example.com/sale" },
"qr_options": { "data": "https://qr-lb.co/summer-sale" }
}
}
Create a link
POST /links
Scope: links.create
Body
| Field | Type | Required | Description |
|---|---|---|---|
name | string | yes | Display name of the link. |
type | string | yes | One of the link types below. |
data | object | yes | Type-specific payload — see link types. |
linkConfigurations | object | no | Slug, scheduling, scan limit, and password — see configuration. |
Example
curl -X POST https://api.prolinksqr.com/links \
-H "Authorization: Basic key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"name": "Summer Sale",
"type": "website",
"data": { "url": "https://example.com/sale" },
"linkConfigurations": {
"urlActive": true,
"customUrl": "summer-sale"
}
}'
Response 200
The new link's identifier (its dynamic_link_id) is returned:
{ "id": "summer-sale" }
Link types
The shape of data depends on type. Supported types and their fields:
website
| Field | Type | Required |
|---|---|---|
url | string (URL) | yes |
email
| Field | Type | Required |
|---|---|---|
email | string (email) | yes |
subject | string | no |
body | string | no |
sms
| Field | Type | Required |
|---|---|---|
phone | string | yes |
message | string | no |
vcard
| Field | Type | Required |
|---|---|---|
firstName, lastName | string | yes |
email | string (email) | yes |
contact, phone, fax, website, company, department, street, state, city, zip, country | string | no |
wifi
| Field | Type | Required | Notes |
|---|---|---|---|
ssid | string | yes | Network name. |
encryption | string | yes | One of WPA, WEP, nopass. |
password | string | no | |
hidden | boolean | no |
location
| Field | Type | Required |
|---|---|---|
latitude | number | yes |
longitude | number | yes |
event
| Field | Type | Required | Notes |
|---|---|---|---|
description, location | string | yes | |
startDateTime | string | yes | Parseable date/time. |
timezone | string | yes | Max 64 chars. |
endDateTime | string | no | Must be ≥ startDateTime. |
organizerName, registrationUrl | string | no | registrationUrl must be a valid URL. |
image / pdf
| Field | Type | Required | Notes |
|---|---|---|---|
files | array | yes | At least one { "fileId": "..." }. Upload files first to obtain a fileId. |
landing
| Field | Type | Required | Notes |
|---|---|---|---|
landingHTML | string | yes | HTML for the landing page. |
product
| Field | Type | Required | Notes |
|---|---|---|---|
productName, productDescription, currency | string | yes | |
subTotal, tax, totalNet | number | yes | Must be ≥ 0. |
discount | object | no | { "type": "amount"|"percent", "value": number }. |
images | object | no | { "files": [{ "fileId": "..." }] }. |
multi-links
| Field | Type | Required | Notes |
|---|---|---|---|
title | string | yes | |
design | object | yes | { "backgroundColor", "linkBackgroundColor", "textColor" }. |
description | string | no | |
logo | any | no | |
isRound | boolean | no | |
links | array | no | Items { "type": "custom"|"social", "value": "<url>", "title"?, "icon"? }. title is required for custom; icon for social. |
multi-pdf
| Field | Type | Required | Notes |
|---|---|---|---|
pageTitle | string | yes | Max 100 chars. |
pdfs | array | yes | 1–10 items of { "label": "...", "fileId": "..." }. |
smart-url
| Field | Type | Required | Notes |
|---|---|---|---|
defaultUrl | string (URL) | yes | Fallback destination. |
rules | array | no | Up to 10 routing rules (see below). |
Each rule:
| Field | Type | Required | Notes |
|---|---|---|---|
conditionType | string | yes | One of location, time, date, device. |
operator | string | yes | location/device: is, is_not. time: between, not_between. date: after, before, between, not_between. |
url | string (URL) | yes | Destination when the rule matches. |
countries | array | cond. | Required for location. |
timezone | string | cond. | Required for time and date. |
timeFrom, timeTo | string | cond. | Required for time. |
dateFrom, dateTo | string | cond. | Required for date depending on operator. |
devices | array | cond. | Required for device. Values: ios, android, windows, macos, linux, mobile, desktop. |
menu
| Field | Type | Required |
|---|---|---|
name | string | no |
Link configuration
The optional linkConfigurations object controls slug, scheduling, scan limits, and
password protection. Each feature has an *Active toggle; the related fields are only
required when its toggle is true.
| Field | Type | Required when | Notes |
|---|---|---|---|
folder_id | string | — | Place the link in a folder. |
urlActive | boolean | — | Enable a custom slug. |
customUrl | string | urlActive: true | Letters, numbers, -, _ only. Max 64 chars. |
scheduleActive | boolean | — | Enable active window. |
startDate, endDate | date | scheduleActive: true | endDate must be after startDate. |
scheduleTimezone | string | scheduleActive: true | Max 64 chars. |
scanLimitActive | boolean | — | Enable a scan cap. |
scanLimit | number | scanLimitActive: true | Max scans before the link stops resolving. |
passwordProtectedActive | boolean | — | Require a password to open. |
password | string | passwordProtectedActive: true | Max 32 chars. |
Update a link
PUT /links/:id
Scope: links.update
A full update. The body uses the same shape as Create a link
(name, type, data, linkConfigurations).
curl -X PUT https://api.prolinksqr.com/links/summer-sale \
-H "Authorization: Basic key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"name": "Summer Sale (extended)",
"type": "website",
"data": { "url": "https://example.com/sale-extended" }
}'
Response 200
{ "data": { "dynamic_link_id": "summer-sale", "name": "Summer Sale (extended)" } }
Patch QR options
PATCH /links/:id
Scope: links.update
Updates only the QR code styling for a link, leaving its content untouched. Send the QR
options under a qrCode key.
| Field | Type | Required | Notes |
|---|---|---|---|
qrCode | object | yes | QR options object — see Templates. |
curl -X PATCH https://api.prolinksqr.com/links/summer-sale \
-H "Authorization: Basic key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{
"qrCode": {
"dotsOptions": { "color": "#1E88D4", "type": "rounded" },
"backgroundOptions": { "color": "#ffffff" }
}
}'
Response 200
{ "data": { "dynamic_link_id": "summer-sale", "qr_options": { "dotsOptions": { "color": "#1E88D4" } } } }
Delete (archive) a link
DELETE /links/:id
POST /links/:id/archive
Scope: links.delete
Links are archived (soft-deleted), not permanently removed. Both routes do the same thing.
curl -X DELETE https://api.prolinksqr.com/links/summer-sale \
-H "Authorization: Basic key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Response 200
{ "message": "Link archived" }
Pause and resume
POST /links/:id/pause
POST /links/:id/resume
Scopes: links.pause (pause), links.resume (resume)
A paused link stops resolving until resumed.
curl -X POST https://api.prolinksqr.com/links/summer-sale/pause \
-H "Authorization: Basic key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"
Response 200
{ "message": "Link paused" }
Duplicate a link
POST /links/:id/duplicate
Scope: links.create
Creates a copy of an existing link. Optionally give the copy a new name.
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | no | Max 255 chars. |
curl -X POST https://api.prolinksqr.com/links/summer-sale/duplicate \
-H "Authorization: Basic key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "name": "Summer Sale (copy)" }'
Save a link as a template
POST /links/:id/save-template
Scope: templates.create
Saves the link's QR styling as a reusable template.
| Field | Type | Required | Notes |
|---|---|---|---|
name | string | no | Max 255 chars. |
curl -X POST https://api.prolinksqr.com/links/summer-sale/save-template \
-H "Authorization: Basic key-xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx" \
-H "Content-Type: application/json" \
-d '{ "name": "Brand QR style" }'