Schnellstart
- Öffne in deinem Dashboard API-Schlüssel (Business-Plan) und erstelle einen Schlüssel. Kopiere ihn: Er wird nur einmal angezeigt.
- Speichere ihn als Umgebungsvariable auf deinem Server, z. B. TESSERA_API_KEY. Gib ihn niemals in Browser- oder App-Code ein.
- Erstelle einen dynamischen QR-Code. Die Antwort enthält seinen Kurzlink in url; codiere diesen Link oder lade ein fertiges Bild über /qr herunter.
cURL
curl "https://scanmosaic.com/api/v1/items" \
-H "Authorization: Bearer $TESSERA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"kind": "qr", "name": "Table menu", "dest": "https://example.com/menu"}'JavaScript
const res = await fetch("https://scanmosaic.com/api/v1/items", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.TESSERA_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
"kind": "qr",
"name": "Table menu",
"dest": "https://example.com/menu"
})
});
const body = await res.json();
if (!res.ok) throw new Error(body.error.message);
console.log(body.data);Python
import os, requests
r = requests.post(
"https://scanmosaic.com/api/v1/items",
headers={"Authorization": f"Bearer {os.environ['TESSERA_API_KEY']}"},
json={
"kind": "qr",
"name": "Table menu",
"dest": "https://example.com/menu"
},
)
r.raise_for_status()
print(r.json()["data"])cURL
curl "https://scanmosaic.com/api/v1/qr?item=k3Xp9Qa&size=1024" \
-H "Authorization: Bearer $TESSERA_API_KEY" \
-o menu.pngJavaScript
import { writeFile } from "node:fs/promises";
const res = await fetch("https://scanmosaic.com/api/v1/qr?item=k3Xp9Qa&size=1024", {
headers: { Authorization: `Bearer ${process.env.TESSERA_API_KEY}` },
});
if (!res.ok) throw new Error((await res.json()).error.message);
await writeFile("menu.png", Buffer.from(await res.arrayBuffer()));Python
import os, requests
r = requests.get(
"https://scanmosaic.com/api/v1/qr?item=k3Xp9Qa&size=1024",
headers={"Authorization": f"Bearer {os.environ['TESSERA_API_KEY']}"},
)
r.raise_for_status()
open("menu.png", "wb").write(r.content)Authentifizierung
Sende deinen Schlüssel im Authorization-Header jeder Anfrage. Schlüssel beginnen mit tsk_ und gehören zu einem Workspace: Sie können alles lesen und ändern, was ein Editor dieses Workspace kann, und nichts in anderen Workspaces.
Authorization: Bearer tsk_AbC123…
- Inhaber und Admins erstellen und löschen Schlüssel im Dashboard unter API-Schlüssel. Ein gelöschter Schlüssel funktioniert sofort nicht mehr.
- Die API gehört zum Business-Tarif. Wenn der Tarif endet, erhalten Anfragen 402 business_required, bis du verlängerst; deine Codes und Daten bleiben erhalten.
- Änderungen mit einem Schlüssel erscheinen im Aktivitätsprotokoll des Workspace als „API key tsk_…“.
- CORS ist offen, sodass du die API von jedem Ursprung aus aufrufen kannst. Ein Schlüssel in einer Webseite kann aber von jedem kopiert werden, der sie öffnet. Rufe die API von deinem Server aus auf.
Fehler
Jeder Fehler hat dieselbe JSON-Form und einen passenden HTTP-Status. code ist stabil: Bau darauf auf. message ist einfaches Englisch für Logs und Menschen. Manche Fehler liefern Details wie param.
{
"error": {
"code": "bad_param",
"message": "One of the parameters isn't valid.",
"status": 400,
"param": "size",
"hint": "64 to 2048"
}
}
| Status | Code | Bedeutung |
|---|---|---|
| 400 | bad_json | Der Body ist kein gültiges JSON. |
| 400 | bad_param | Ein Query- oder Body-Parameter liegt außerhalb des gültigen Bereichs. details: param, hint. |
| 400 | bad_destination | dest ist keine vollständige http(s)-Webadresse. |
| 400 | bad_kind | kind ist weder qr, link noch barcode. |
| 400 | bad_alias | alias besteht nicht aus 3–40 Buchstaben, Ziffern oder Bindestrichen oder ist reserviert. |
| 400 | domain_not_verified | domain ist keine verifizierte Domain deines Workspaces. |
| 400 | unsafe_destination | Google Web Risk stuft das Ziel als riskant ein. |
| 400 | empty / too_long / bad_format | QR-Bilder: keine Daten, zu viele Daten oder ein anderes Format als png oder svg. |
| 400 | bad_cursor | Dieser Cursor stammt nicht von uns. |
| 401 | api_key_required | Kein Authorization-Header, oder er ist nicht Bearer tsk_… |
| 401 | invalid_api_key | Der Schlüssel existiert nicht oder wurde gelöscht. |
| 402 | business_required | Der Workspace hat keinen Business-Tarif (zum Beispiel, weil er beendet wurde). |
| 403 | limit_reached | Das Limit deines Plans für diese Art von Element ist erreicht. details: limit, kind. |
| 404 | not_found | Dieses Element gibt es in diesem Workspace nicht. |
| 409 | alias_taken | Dieser Alias wird auf dieser Domain bereits verwendet. |
| 413 | too_big | Der Body ist zu groß (250 KB für Items). |
| 429 | rate_limited / daily_limit | Zu viele Anfragen. Warte die unter Retry-After angegebenen Sekunden. |
| 500 | server_error | Bei uns ist etwas schiefgelaufen. Versuche es mit zunehmenden Wartezeiten erneut. |
Ratenlimits
Jeder Schlüssel kann 120 Anfragen pro Minute und 20,000 pro Tag senden. Jede Antwort zeigt dir, wo du stehst:
| Kopfbereich | Bedeutung |
|---|---|
X-RateLimit-Limit | Erlaubte Anfragen pro Minute. |
X-RateLimit-Remaining | Verbleibende Anfragen in der aktuellen Minute. |
X-RateLimit-Reset | Unix-Zeit, zu der die Minute zurückgesetzt wird. |
Retry-After | Nur bei 429: Sekunden, die du vor dem nächsten Versuch warten sollst. |
Das Erstellen von Elementen ist außerdem auf 300 pro Stunde und Workspace begrenzt, und dein Tarif legt fest, wie viele Elemente du behalten kannst. Brauchst du mehr? Schreib uns.
Seitennavigation
Listen liefern die neuesten zuerst, bis zu limit Elemente (Standard 25, höchstens 100). Wenn has_more true ist, übergib next_cursor als cursor, um die nächste Seite zu erhalten. Cursor bleiben gültig, wenn Elemente hinzukommen.
{
"data": [
"\u2026"
],
"has_more": true,
"next_cursor": "MTc2NzIyNTYwMC5rM1hwOVFh"
}
Das Item-Objekt
QR-Codes, Links und Barcodes sind alle Items. Einzelne Items kommen als data zurück, Listen als data mit Paging-Feldern.
| Name | Typ | Beschreibung |
|---|---|---|
id | string | Kurze ID, zugleich die Standard-Endung des Kurzlinks. |
kind | qr | link | barcode | Was es ist. Lässt sich nach dem Erstellen nicht mehr ändern. |
type | string | Inhaltstyp, z. B. url (Standard), pdf, menu, vcard für QR-Codes; ean13, code128 für Barcodes. |
name | string | Deine Bezeichnung, bis zu 80 Zeichen. |
dest | string | null | Wohin Scans und Klicks führen. null bei gehosteten Seiten und Barcodes. |
url | string | Der Kurzlink, den der QR-Code kodiert, z. B. https://go.yourbrand.com/menu. |
alias | string | null | Eigene Endung (3–40 Buchstaben, Zahlen oder Bindestriche), pro Domain einmalig. |
domain | string | null | Deine verifizierte eigene Domain oder null für unsere. |
campaign | string | null | Elemente für Berichte gruppieren. |
content | object | null | Daten der gehosteten Seite oder Barcode-Daten ({ "data": "…" }). |
style | object | Design des QR-Codes (Farben, Punkt- und Eckenstile). |
rules | object | null | Routing-Regeln (nach Gerät, Land, Zeit …). |
paused | boolean | Pausierte Elemente zeigen eine „pausiert“-Seite statt weiterzuleiten. |
disabled | boolean | Von uns wegen Verstoßes gegen die Bedingungen deaktiviert. |
hits | integer | Scans insgesamt (QR-Codes) oder Klicks (Links). |
last_hit | integer | null | Unix-Zeit des letzten Scans oder Klicks. |
created / updated | integer | Unix-Zeiten. |
Endpunkte
GET /api/v1/me
Konto
Der Workspace, zu dem dieser Schlüssel gehört, sein Tarif, Limits, Nutzung, verifizierte Domains und Ratenlimits. Praktisch, um zu prüfen, ob ein Schlüssel funktioniert.
cURL
curl "https://scanmosaic.com/api/v1/me" \
-H "Authorization: Bearer $TESSERA_API_KEY"JavaScript
const res = await fetch("https://scanmosaic.com/api/v1/me", {
headers: { Authorization: `Bearer ${process.env.TESSERA_API_KEY}` },
});
const body = await res.json();
if (!res.ok) throw new Error(body.error.message);
console.log(body.data);Python
import os, requests
r = requests.get(
"https://scanmosaic.com/api/v1/me",
headers={"Authorization": f"Bearer {os.environ['TESSERA_API_KEY']}"},
)
r.raise_for_status()
print(r.json()["data"])Antwort 200 OK
{
"data": {
"workspace": {
"id": "w_8fK2mQ",
"name": "Acme"
},
"plan": "business",
"key": {
"prefix": "tsk_AbC123",
"name": "Shopify sync"
},
"limits": {
"qr": 1000,
"link": 5000,
"barcode": 10000,
"domains": 5
},
"usage": {
"dynamic": 12,
"links": 40,
"barcodes": 3,
"storageBytes": 0,
"workspaces": 1
},
"domains": [
"go.yourbrand.com"
],
"rate_limits": {
"per_minute": 120,
"per_day": 20000
}
}
}GET /api/v1/items
Elemente auflisten
Elemente im Workspace, neueste zuerst.
| Name | Typ | Beschreibung |
|---|---|---|
kind | qr | link | barcode | Nur diese Art. |
type | string | Nur dieser Inhaltstyp, z. B. url oder pdf. |
campaign | string | Nur diese Kampagne. |
domain | string | Nur Elemente auf dieser eigenen Domain. |
paused | true | false | Nur pausierte oder nur aktive Elemente. |
q | string | Suche nach Name, Ziel und Alias. |
limit | integer | 1–100, Standard 25. |
cursor | string | next_cursor von der vorherigen Seite. |
cURL
curl "https://scanmosaic.com/api/v1/items?kind=link&campaign=spring&limit=50" \
-H "Authorization: Bearer $TESSERA_API_KEY"JavaScript
const res = await fetch("https://scanmosaic.com/api/v1/items?kind=link&campaign=spring&limit=50", {
headers: { Authorization: `Bearer ${process.env.TESSERA_API_KEY}` },
});
const body = await res.json();
if (!res.ok) throw new Error(body.error.message);
console.log(body.data);Python
import os, requests
r = requests.get(
"https://scanmosaic.com/api/v1/items?kind=link&campaign=spring&limit=50",
headers={"Authorization": f"Bearer {os.environ['TESSERA_API_KEY']}"},
)
r.raise_for_status()
print(r.json()["data"])Antwort 200 OK
{
"data": [
{
"id": "k3Xp9Qa",
"kind": "link",
"type": "url",
"name": "Spring menu",
"dest": "https://example.com/menu",
"content": null,
"style": {},
"rules": null,
"alias": "menu",
"domain": "go.yourbrand.com",
"campaign": "spring",
"og": null,
"created": 1767225600,
"updated": 1767225600,
"paused": false,
"disabled": false,
"hits": 42,
"last_hit": 1767312000,
"url": "https://go.yourbrand.com/menu"
}
],
"has_more": false,
"next_cursor": null
}POST /api/v1/items
Element erstellen
Erstellt einen dynamischen QR-Code, Kurzlink oder gespeicherten Barcode. Zählt zu den Limits deines Plans.
| Name | Typ | Beschreibung |
|---|---|---|
kind | qr | link | barcode | Standard qr. |
dest erforderlich | string | Vollständige http(s)-Adresse für die Weiterleitung. Wird für Barcodes und gehostete Seiten nicht verwendet. |
name | string | Bis zu 80 Zeichen. |
type | string | Standard url (Codes, Links) oder code128 (Barcodes). |
alias | string | Eigene Endung, z. B. menu. 3–40 Buchstaben, Zahlen oder Bindestriche, pro Domain einmalig. |
domain | string | Eine deiner verifizierten eigenen Domains (siehe /domains). |
campaign | string | Bis zu 60 Zeichen. |
style | object | QR-Design, z. B. {"fg": "#112233", "dot": "rounded"}. |
content | object | Daten der gehosteten Seite oder Barcode-Daten, z. B. {"bcid": "ean13", "text": "4006381333931"} für einen Barcode. |
rules | object | Routing-Regeln. |
paused | boolean | Pausiert starten. |
cURL
curl "https://scanmosaic.com/api/v1/items" \
-H "Authorization: Bearer $TESSERA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"kind": "link", "name": "Spring menu", "dest": "https://example.com/menu", "alias": "menu", "domain": "go.yourbrand.com", "campaign": "spring"}'JavaScript
const res = await fetch("https://scanmosaic.com/api/v1/items", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.TESSERA_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
"kind": "link",
"name": "Spring menu",
"dest": "https://example.com/menu",
"alias": "menu",
"domain": "go.yourbrand.com",
"campaign": "spring"
})
});
const body = await res.json();
if (!res.ok) throw new Error(body.error.message);
console.log(body.data);Python
import os, requests
r = requests.post(
"https://scanmosaic.com/api/v1/items",
headers={"Authorization": f"Bearer {os.environ['TESSERA_API_KEY']}"},
json={
"kind": "link",
"name": "Spring menu",
"dest": "https://example.com/menu",
"alias": "menu",
"domain": "go.yourbrand.com",
"campaign": "spring"
},
)
r.raise_for_status()
print(r.json()["data"])Antwort 201 Created
{
"data": {
"id": "k3Xp9Qa",
"kind": "link",
"type": "url",
"name": "Spring menu",
"dest": "https://example.com/menu",
"content": null,
"style": {},
"rules": null,
"alias": "menu",
"domain": "go.yourbrand.com",
"campaign": "spring",
"og": null,
"created": 1767225600,
"updated": 1767225600,
"paused": false,
"disabled": false,
"hits": 42,
"last_hit": 1767312000,
"url": "https://go.yourbrand.com/menu"
}
}GET /api/v1/items/{id}
Artikel holen
Ein Element per ID.
cURL
curl "https://scanmosaic.com/api/v1/items/k3Xp9Qa" \
-H "Authorization: Bearer $TESSERA_API_KEY"JavaScript
const res = await fetch("https://scanmosaic.com/api/v1/items/k3Xp9Qa", {
headers: { Authorization: `Bearer ${process.env.TESSERA_API_KEY}` },
});
const body = await res.json();
if (!res.ok) throw new Error(body.error.message);
console.log(body.data);Python
import os, requests
r = requests.get(
"https://scanmosaic.com/api/v1/items/k3Xp9Qa",
headers={"Authorization": f"Bearer {os.environ['TESSERA_API_KEY']}"},
)
r.raise_for_status()
print(r.json()["data"])Antwort 200 OK
{
"data": {
"id": "k3Xp9Qa",
"kind": "link",
"type": "url",
"name": "Spring menu",
"dest": "https://example.com/menu",
"content": null,
"style": {},
"rules": null,
"alias": "menu",
"domain": "go.yourbrand.com",
"campaign": "spring",
"og": null,
"created": 1767225600,
"updated": 1767225600,
"paused": false,
"disabled": false,
"hits": 42,
"last_hit": 1767312000,
"url": "https://go.yourbrand.com/menu"
}
}PATCH /api/v1/items/{id}
Eintrag aktualisieren
Sende nur die Felder, die sich ändern sollen. Eine Änderung von dest gilt ab dem nächsten Scan; gedruckte Codes funktionieren weiter. Eine Änderung von domain oder alias ändert den Kurzlink, sodass bereits gedruckte Codes nicht mehr funktionieren.
| Name | Typ | Beschreibung |
|---|---|---|
name, dest, alias, domain, campaign, style, content, rules, paused | Wie bei „Erstellen“. kind lässt sich nicht ändern. Sende null, um alias, domain, campaign oder rules zu leeren. |
cURL
curl -X PATCH "https://scanmosaic.com/api/v1/items/k3Xp9Qa" \
-H "Authorization: Bearer $TESSERA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"dest": "https://example.com/summer-menu", "paused": false}'JavaScript
const res = await fetch("https://scanmosaic.com/api/v1/items/k3Xp9Qa", {
method: "PATCH",
headers: { Authorization: `Bearer ${process.env.TESSERA_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
"dest": "https://example.com/summer-menu",
"paused": false
})
});
const body = await res.json();
if (!res.ok) throw new Error(body.error.message);
console.log(body.data);Python
import os, requests
r = requests.patch(
"https://scanmosaic.com/api/v1/items/k3Xp9Qa",
headers={"Authorization": f"Bearer {os.environ['TESSERA_API_KEY']}"},
json={
"dest": "https://example.com/summer-menu",
"paused": False
},
)
r.raise_for_status()
print(r.json()["data"])Antwort 200 OK
{
"data": {
"id": "k3Xp9Qa",
"kind": "link",
"type": "url",
"name": "Spring menu",
"dest": "https://example.com/summer-menu",
"content": null,
"style": {},
"rules": null,
"alias": "menu",
"domain": "go.yourbrand.com",
"campaign": "spring",
"og": null,
"created": 1767225600,
"updated": 1767225600,
"paused": false,
"disabled": false,
"hits": 42,
"last_hit": 1767312000,
"url": "https://go.yourbrand.com/menu"
}
}DELETE /api/v1/items/{id}
Element löschen
Löscht das Element und seinen Scan-Verlauf. Sein Kurzlink funktioniert sofort nicht mehr. Das lässt sich nicht rückgängig machen.
cURL
curl -X DELETE "https://scanmosaic.com/api/v1/items/k3Xp9Qa" \
-H "Authorization: Bearer $TESSERA_API_KEY"JavaScript
const res = await fetch("https://scanmosaic.com/api/v1/items/k3Xp9Qa", {
method: "DELETE",
headers: { Authorization: `Bearer ${process.env.TESSERA_API_KEY}` },
});
const body = await res.json();
if (!res.ok) throw new Error(body.error.message);
console.log(body.data);Python
import os, requests
r = requests.delete(
"https://scanmosaic.com/api/v1/items/k3Xp9Qa",
headers={"Authorization": f"Bearer {os.environ['TESSERA_API_KEY']}"},
)
r.raise_for_status()
print(r.json()["data"])Antwort 200 OK
{
"data": {
"id": "k3Xp9Qa",
"deleted": true
}
}GET /api/v1/items/{id}/stats
Element-Statistiken
Scans oder Klicks über einen Zeitraum: eine Tagesreihe und Aufschlüsselungen nach Land, Gerät, Betriebssystem, Browser, Sprache und Routing-Regel. Bots werden nicht gezählt.
| Name | Typ | Beschreibung |
|---|---|---|
days | integer | 1–365, Standard 30. |
cURL
curl "https://scanmosaic.com/api/v1/items/k3Xp9Qa/stats?days=7" \
-H "Authorization: Bearer $TESSERA_API_KEY"JavaScript
const res = await fetch("https://scanmosaic.com/api/v1/items/k3Xp9Qa/stats?days=7", {
headers: { Authorization: `Bearer ${process.env.TESSERA_API_KEY}` },
});
const body = await res.json();
if (!res.ok) throw new Error(body.error.message);
console.log(body.data);Python
import os, requests
r = requests.get(
"https://scanmosaic.com/api/v1/items/k3Xp9Qa/stats?days=7",
headers={"Authorization": f"Bearer {os.environ['TESSERA_API_KEY']}"},
)
r.raise_for_status()
print(r.json()["data"])Antwort 200 OK
{
"data": {
"days": 7,
"total": 42,
"last_hit": 1767312000,
"inRange": 12,
"series": [
[
"2026-01-01",
3
],
[
"2026-01-02",
0
],
[
"…",
0
]
],
"countries": [
{
"k": "GB",
"n": 7
},
{
"k": "US",
"n": 5
}
],
"devices": [
{
"k": "Mobile",
"n": 10
},
{
"k": "Desktop",
"n": 2
}
],
"os": [
{
"k": "iOS",
"n": 6
}
],
"browsers": [
{
"k": "Safari",
"n": 6
}
],
"langs": [
{
"k": "en-gb",
"n": 7
}
],
"rules": [
{
"k": "default",
"n": 12
}
]
}
}GET /api/v1/qr
QR-Code-Bild
Rendert einen QR-Code als PNG oder SVG. Nutze GET mit Query-Parametern oder sende dieselben Parameter per POST als JSON. Übergib item, um einen gespeicherten Code mit eigenem Design und Kurzlink zu zeichnen, oder data für beliebigen Text.
| Name | Typ | Beschreibung |
|---|---|---|
data | string | Text oder Link zum Kodieren (bis zu 2.953 Bytes). Erforderlich, sofern item nicht gesetzt ist. |
item | string | ID eines gespeicherten QR-Codes oder Links: kodiert seinen Kurzlink mit dem gespeicherten Design. |
format | png | svg | Standard png. |
size | integer | Pixel, 64–2048 für PNG (Standard 512), 64–4096 für SVG (Standard 1024). |
color | #RRGGBB | Punkte. Standard #141A2E. |
background | #RRGGBB | Standard #FFFFFF. |
transparent | boolean | Transparenter Hintergrund. |
corner_color | #RRGGBB | Eckquadrate. Standard: color. |
gradient_color | #RRGGBB | Nur SVG: zweite Farbe eines diagonalen Verlaufs. |
error_correction | L | M | Q | H | Wie viel Beschädigung der Code übersteht: 7 %, 15 %, 25 %, 30 %. Standard M (PNG) oder Q (SVG). |
margin | integer | Ruhezone in Modulen, 0–8. Standard 4. |
dot_style | string | square, dots, rounded, extra-rounded, classy, classy-rounded |
corner_style | string | square, extra-rounded, dot |
corner_dot_style | string | square, dot |
download | string | Dateiname: fügt Content-Disposition: attachment hinzu. |
PNGs werden auf unseren Servern mit ganzen Pixeln pro Modul gezeichnet, sodass die Kanten für den Druck scharf bleiben. Verläufe und Logos gibt es nur als SVG; für Logos nutze den Generator.
cURL
curl "https://scanmosaic.com/api/v1/qr" \
-H "Authorization: Bearer $TESSERA_API_KEY" \
-H "Content-Type: application/json" \
-d '{"data": "https://example.com", "format": "png", "size": 1024, "color": "#4865F0", "dot_style": "rounded", "corner_style": "extra-rounded"}' \
-o qr.pngJavaScript
import { writeFile } from "node:fs/promises";
const res = await fetch("https://scanmosaic.com/api/v1/qr", {
method: "POST",
headers: { Authorization: `Bearer ${process.env.TESSERA_API_KEY}`, "Content-Type": "application/json" },
body: JSON.stringify({
"data": "https://example.com",
"format": "png",
"size": 1024,
"color": "#4865F0",
"dot_style": "rounded",
"corner_style": "extra-rounded"
})
});
if (!res.ok) throw new Error((await res.json()).error.message);
await writeFile("qr.png", Buffer.from(await res.arrayBuffer()));Python
import os, requests
r = requests.post(
"https://scanmosaic.com/api/v1/qr",
headers={"Authorization": f"Bearer {os.environ['TESSERA_API_KEY']}"},
json={
"data": "https://example.com",
"format": "png",
"size": 1024,
"color": "#4865F0",
"dot_style": "rounded",
"corner_style": "extra-rounded"
},
)
r.raise_for_status()
open("qr.png", "wb").write(r.content)GET /api/v1/domains
Domains
Die eigenen Domains des Workspace. Verwende beim Erstellen von Items einen Host, bei dem ready true ist, als domain.
cURL
curl "https://scanmosaic.com/api/v1/domains" \
-H "Authorization: Bearer $TESSERA_API_KEY"JavaScript
const res = await fetch("https://scanmosaic.com/api/v1/domains", {
headers: { Authorization: `Bearer ${process.env.TESSERA_API_KEY}` },
});
const body = await res.json();
if (!res.ok) throw new Error(body.error.message);
console.log(body.data);Python
import os, requests
r = requests.get(
"https://scanmosaic.com/api/v1/domains",
headers={"Authorization": f"Bearer {os.environ['TESSERA_API_KEY']}"},
)
r.raise_for_status()
print(r.json()["data"])Antwort 200 OK
{
"data": [
{
"host": "go.yourbrand.com",
"verified": true,
"ready": true
}
]
}Eigene Domains
Mit dem Business-Plan können deine Kurzlinks deine eigene Domain nutzen, z. B. go.yourbrand.com/menu. Füge die Domain im Dashboard unter Domains hinzu und verifiziere sie: Du legst einen CNAME-Eintrag an, der auf uns zeigt, und einen TXT-Eintrag, der beweist, dass die Domain dir gehört, und wir stellen das SSL-Zertifikat aus. Übergib dann domain, wenn du ein Element erstellst oder aktualisierst.
Jede Domain kann ihre nackte Adresse (go.yourbrand.com) und unbekannte Pfade auf Seiten deiner Wahl weiterleiten.
OpenAPI
Die vollständige API ist in openapi.json (OpenAPI 3.1) beschrieben. Importiere sie in Postman, Insomnia oder einen Client-Generator.
Versionierung
v1 ist stabil. Wir können Endpunkte, Felder und Fehlercodes hinzufügen, ignoriere also Felder, die du nicht kennst. In v1 entfernen oder benennen wir nichts um; Breaking Changes kämen als v2 und würden rechtzeitig angekündigt.