
A practical problem: the summer menu is printed — but the offers are changing
Imagine: your restaurant chain has printed hundreds of table tents and posters with QR codes linking to promotions. Now the summer season begins — multiple offers must be replaced or activated on schedule. Reprinting is expensive and slow. The solution: update dynamic QR targets centrally and do it in batch via API, without changing a single printed piece.
Why a bulk update via API makes sense
- The printed QR code remains unchanged; you only change the target.
- Central management: media, branding and targets stay in one place.
- Quickly scalable: seasonal campaigns for hundreds or thousands of shortlinks in one run.
- Integration: automatable from your ERP, CMS or a marketing planner.
Prerequisites and procedure
Before you start, clarify these points:
- API access: API token/key and the base URL of your Linkentra instance (cloud or self‑hosted).
- Field mapping: which fields the API expects (target URL, title, slug/shortcode, active/disabled, scheduled rules). Adjust the example payloads to your API documentation.
- Batch size: test with small batches (e.g. 50–200) and then increase size depending on rate limits.
- Backup: export existing shortlinks/IDs before changes (CSV/JSON) so you can plan a rollback.
Practical case: workflow for a seasonal campaign
Sequence of steps at a glance:
- Export all relevant shortlinks (e.g. category "Summer Promo") with IDs.
- Create a dataset with new target URLs and optional media/meta.
- Batch update via API: assign new targets, adjust title/branding, set scheduling.
- Monitoring: checks on status codes, simple scan verification after publication.
PHP example: bulk creation of QR targets
The script below is intended as a template. Replace $apiBase, $token and the endpoints with the actual values from your Linkentra documentation.
// Configuration
$apiBase = 'https://IHRE‑LINKENTRA‑INSTANZ'; // Base API URL of your instance
$token = 'MEIN_API_TOKEN';
$batchSize = 100; // Number per run
// Example data: an array with targets for the season
$items = [
['slug'=>'sommer-angebot-1', 'target'=>'https://example.com/sommer/angebot1', 'title'=>'Sommer Angebot 1'],
['slug'=>'sommer-angebot-2', 'target'=>'https://example.com/sommer/angebot2', 'title'=>'Sommer Angebot 2'],
// ... more entries
];
function apiRequest($method, $path, $data = null) {
global $apiBase, $token;
$url = rtrim($apiBase, '/') . '/' . ltrim($path, '/');
$ch = curl_init($url);
$headers = [ 'Authorization: Bearer ' . $token, 'Accept: application/json' ];
if ($data !== null) {
$payload = json_encode($data);
$headers[] = 'Content-Type: application/json';
curl_setopt($ch, CURLOPT_POSTFIELDS, $payload);
}
curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
curl_setopt($ch, CURLOPT_HTTPHEADER, $headers);
// Set method
switch (strtoupper($method)) {
case 'POST': curl_setopt($ch, CURLOPT_POST, true); break;
case 'PUT': curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PUT'); break;
case 'PATCH': curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'PATCH'); break;
case 'DELETE': curl_setopt($ch, CURLOPT_CUSTOMREQUEST, 'DELETE'); break;
}
$resp = curl_exec($ch);
$http = curl_getinfo($ch, CURLINFO_HTTP_CODE);
if ($resp === false) { $err = curl_error($ch); curl_close($ch); throw new Exception('cURL error: '.$err); }
curl_close($ch);
return ['http'=>$http, 'body'=>json_decode($resp, true)];
}
// Batch creation
$chunks = array_chunk($items, $batchSize);
foreach ($chunks as $i => $chunk) {
foreach ($chunk as $entry) {
$payload = [
'slug' => $entry['slug'],
'target' => $entry['target'],
'title' => $entry['title'],
// additional fields as needed: branding, media_id, start_at, end_at
];
$res = apiRequest('POST', '/targets', $payload); // adjust path
if ($res['http'] >= 200 && $res['http'] < 300) {
// Success: store or log the ID
// Example: file_put_contents('created_ids.csv', $res['body']['id']."\n", FILE_APPEND);
} else {
// Error handling: retry/log
}
}
// short pause between batches to respect rate limits
sleep(1);
}
?>
PHP example: Bulk update (e.g. to new target URLs for the season)
If you want to update existing short links, you typically work with the IDs you exported when creating them.
// Example: $updates = [ ['id'=>123, 'target'=>'https://...'], ... ];
foreach ($updates as $u) {
$payload = ['target' => $u['target']];
$res = apiRequest('PATCH', '/targets/'.$u['id'], $payload); // Adjust path/field names
if ($res['http'] >= 200 && $res['http'] < 300) {
// OK
} else {
// Log and optionally implement retry
}
usleep(200000); // 200ms pause
}
?>
PHP example: Deactivate (temporarily) or delete
Depending on the desired behavior, deactivate links (the shortlink remains but does not redirect) or delete it.
// Deactivate via PATCH
foreach ($idsToDeactivate as $id) {
$res = apiRequest('PATCH', '/targets/'.$id, ['active' => false]);
// Or: apiRequest('DELETE', '/targets/'.$id); if deletion is desired
}
?>
CSV bulk: Hybrid approach (generate CSV, use API/import)
Linkentra offers bulk import options (CSV/JSON) as an alternative to a pure API loop. A proven procedure:
- 1) Generate a CSV with columns for slug,target,title,start_at,end_at.
- 2) Validate the CSV locally (duplicates, invalid URLs, missing slugs).
- 3) Upload the file via API upload or through the web interface.
PHP snippet to generate the CSV (example):
$fp = fopen('bulk_import.csv', 'w');
fputcsv($fp, ['slug','target','title','start_at','end_at']);
foreach ($items as $row) { fputcsv($fp, [$row['slug'],$row['target'],$row['title'],'','']); }
fclose($fp);
// Then upload via API or button in the admin interface
?>
Practical tips for robust automation
- Try batch size: too large = timeouts, too small = long runtimes.
- Handle HTTP responses and status codes; implement backoff strategy on 429/5xx.
- Idempotency: Use slugs or external IDs so repeated requests do not create duplicates.
- Logging & backup: Store old target URLs and link IDs for quick rollback.
- Scheduling: If the API supports time fields, set start_at/end_at instead of activating manually.
- Security: Keep API tokens safe (environment variables, secrets manager).
Integration into daily operations
For marketing teams and operators this means: plan campaigns as a dataset (CSV or DB table), automate publishing via script and monitor scans with the usage overviews. In self‑hosted installations IT admins retain data ownership; the cloud option allows faster onboarding.
Conclusion and next steps
Bulk updates via API greatly simplify seasonal changes: you avoid reprinting, manage targets centrally and can roll them out on a schedule. Use the provided PHP templates as a starting point, adjust paths and field names to your Linkentra‑API and test with small groups before rolling out widely.
Try it now: Discover Linkentra and test it in your own environment: https://linkentra.de
If you like, I can adapt the sample scripts to your actual Linkentra‑API documentation (endpoint path, expected field names, authentication type) — give me the details and I'll create a ready integration script.
Next step
Try Linkentra yourself
Dynamic QR codes with control over hosting and data: change content afterwards, adjust branding, manage media centrally and analyze scans – optionally on your own infrastructure (Self‑Hosted) or immediately in the Linkentra Cloud. Edition-dependent features for teams, API and white-label.
