Pull DTG job using barcode/QR-code scanner

Pull DTG job using barcode/QR-code scanner

The common workflow for a DTG job consist of the following steps:
  1. Upload the job using /api/v2/job without specifying the DeviceGUID. This puts the job in a generic holding queue.
  2. Pull the job its preview on the display at the moment the job its barcode/QR-code is scanned using /api/v2/{JobGUID}/thumbnail/1
  3. Send the job to a specific device using /api/v2/job/{JobGUID}/device/{DeviceGUID} when the operator confirms the job
The above is a sample flow, your production process could require a different flow, for example skipping step 2.

The demonstrate this behavior a self-contained HTML is available at this URL. This tool implements a webpage that could run on the screen of the printer or in the webbrowser of a mobile phone.

What is does

  1. Decode a job-bag QR (URL form), extract the job GUID and page number.
  2. Preview the job (thumbnail and job metadata).
  3. Send the job to a selected DeviceGUID using the PrintFactory API.
  4. Supports handheld barcode/QR scanners (keyboard-emulation) and camera scanning.
  5. Stores your configuration locally so you can reopen the page and continue quickly.

Before you start

  1. Download the tool files
    Put the Scanner.html file and the private copy of html5-qrcode.min.js in the same folder. The page loads ./html5-qrcode.min.js from the same directory.
  2. Recommended browser / camera permissions
    Use a modern browser (Chrome, Edge, Firefox). Grant camera permission when the browser asks. If the camera doesn’t appear, check browser site permissions.

Get credentials & IDs from Hub

You need two things from the Hub before configuring the scanner: the MISKey and the Site#. You also need to know which printer device you want to send jobs to — that is selected from the Site’s devices inside the tool.
  1. Get the MISKey
    1. Open the Hub at: https://app.printfactory.cloud
    2. Sign in and open User Profile (top-right menu).
    3. Go to Settings → External API.
    4. Copy the MISKey value shown there. This is the secret you paste into the scanner’s MISKey field. The tool sends requests with this value in the MISKey: HTTP header.
  2. Get the Site#
    1. In the Hub navigate to Account → Sites.
    2. Find the site you want to use and note the Site# (a numeric ID).
    3. You will enter the Site# into the tool so it can fetch the printers/devices for that site.
  3. Print a Job Bag QR (example)
    To generate a job-bag QR inside the Hub:
    1. In Hub, go to Tracking → Print Job Bag → Print.
    2. Print the job bag that contains the QR you will scan.
    3. The printed QR encodes a URL like: http://pfam.cc/id/01JrqHZorpqUEKJso-CZQZdkw/p1
      1. 01J... is the encoded JobGUID (the 01J prefix marks a job).
      2. p1 is the page token: the thumbnail page index to fetch.

Configure the tool

Open the Scanner.html page in your browser. The tool has two screens: Configuration and Scanner. If any required setting is missing, the Configuration screen is shown.
Configuration screen (what to fill)
  1. API Base URL
    1. Default: https://api.aurelon.com/api/v2 or https://api.aurelon.cn/api/v2
    2. You can keep the default unless instructed otherwise.
  2. Site#
    1. Enter the Site# you copied from Hub.
  3. MISKey
    1. Paste the MISKey string from Hub (Settings → External API).
  4. Load printers / devices (button)
    1. Click this after entering the Site#. The tool will call GET {API_BASE}/configuration/site/{site} and populate the device list with Devices[].Name (label) and Devices[].DeviceGUID (value).
  5. Select a device or paste a DeviceGUID
    1. From the dropdown choose the printer device you want to send jobs to, OR paste the DeviceGUID into the Device GUID input if you have it.
    2. The tool stores your chosen DeviceGUID.
  6. Confirm & Continue
    1. This saves all values into your browser (localStorage) and opens the Scanner screen.
Notes
Notes
  1. The tool stores API Base, Site#, MISKey and DeviceGUID locally; they persist between visits.
  2. Use Reset to clear all saved configuration.

Scanner screen — how to use

When configuration is complete you will see the Scanner screen with the scanning UI, camera controls, and job preview/send features.

Scanning (handheld scanner)

  1. Focus the Scanner input field (click it or press the Focus button).
  2. Scan the printed QR with a handheld barcode/QR scanner (most scanners emulate a keyboard and send the scanned text plus Enter).
  3. The tool detects the QR, decodes the job GUID and page, and shows:
    1. Detected JobGUID and Detected Page
    2. A job preview card (title, status, pages, submitted by, created date, priority)
    3. The job thumbnail (fetched from {API_BASE}/job/{JobGUID}/thumbnail/{page})
  4. Click Send to device to send the job to the selected device.

Scanning (camera)

  1. Select a camera from the Camera dropdown. The tool will try to select a back/rear (environment) camera by default where available. The selected camera is stored so the next time it’s preselected.
  2. Click Start camera. A camera preview appears.
  3. When the camera successfully decodes the QR, the tool:
    1. Automatically processes the QR,
    2. Shows the job preview and thumbnail,
    3. Automatically stops the camera.
  4. Use Stop to stop the camera manually.

Preview & Send

  1. After decoding, the tool first fetches the thumbnail and job details:
    1. GET {API_BASE}/job/{JobGUID}/thumbnail/{page} (to get the job thumbnail)
    2. GET {API_BASE}/job/{JobGUID} (to get the job details)
  2. The job card displays job metadata and a thumbnail.
  3. Click Send to device to POST the job to:
    POST {API_BASE}/job/{JobGUID}/device/{DeviceGUID}
    The tool sends your MISKey in the MISKey header.

Reconfigure

      returns to the Configuration screen so you can edit settings; it preserves saved values.

Info

How the QR decoding works

  1. The tool accepts QR content that is a URL of the form:
    http://pfam.cc/id/01{base64Guid}/{pageToken}
    1. The segment after /id/ begins with 01J to identify the JobGUID.
    2. The remainder is an URL-safe Base64 encoding of the binary GUID. The tool:
      1. Replaces _ → / and - → +, appends ==, base64-decodes to 16 bytes
      2. Applies Microsoft GUID byte-order correction (the first 3 fields are little-endian in storage), then formats the GUID as xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx.
    3. The last segment (p1, p2, etc.) provides the thumbnail page index (default is 1).
  2. If the QR contains a plain GUID (hyphenated or 32 hex), the tool accepts that too.
  3. The tool automatically handles GUID byte-order (so you get the correct textual GUID).

Troubleshooting & tips

  1. Camera not listed / does not work
    1. Check browser camera permissions and try reloading the page.
    2. The tool attempts to pick a back/rear camera automatically if available. You can manually choose a different camera from the dropdown; your choice is saved.
  2. Thumbnail or job preview not displayed
    1. Check MISKey and Site# are correct. If the API returns authentication errors (401/403), confirm your MISKey is valid and has appropriate permissions.
    2. If the thumbnail endpoint returns binary/image data the tool will display it. If it returns JSON with base64, the tool will display that too.
  3. Decode fails or wrong GUID
    1. The tool implements the Microsoft GUID endianness fix for JobGUIDs encoded as binary — that resolves the most common "byte-order" mismatch.
    2. If decoding still fails, check the QR content (scan it as text or paste it into the Scanner input to debug). The QR should contain /id/01... or a GUID.
  4. CORS or network errors in browser
    1. If your browser blocks requests (CORS), ensure your environment allows requests to https://api.aurelon.com/api/v2 (or the API_BASE you configured). Network errors will appear in the log area for debugging.
  5. Persistent settings
    1. The tool saves API Base, Site#, MISKey, DeviceGUID and selected camera locally in the browser (localStorage). Use Reset to clear them.
  6. Handheld scanner tips
    1. If using a handheld that emulates a keyboard, ensure the Scanner input is focused before scanning, or press the Focus button.

Example workflow (quick)

  1. Get MISKey from Hub → User Profile → Settings → External API.
  2. Get Site# from Hub → Account → Sites.
  3. Print a job bag QR in Hub → Tracking → Print Job Bag → Print.
  4. Open the tool (https://download.printfactory.cloud/DemoAutomation/DTG/Scanner.html), fill API Base, Site#, paste MISKey, click Load printers.
  5. Select a device or paste a DeviceGUID, click Confirm & Continue.
  6. On the Scanner screen:
    1. Focus the input and scan the QR, or
    2. Select a camera and click Start camera and point the camera at the printed QR.
  7. Confirm the preview (job name and thumbnail) appears.
  8. Click Send to device to send the job to the printer.

Development guide

Below is a concise, practical developer guide showing exactly which APIs on api.aurelon.com you should call and how to call them to build the scanner/preview/send tool yourself. It includes request/response shapes, headers, error-handling tips, and working JavaScript examples for each step (configuration → decode QR → preview → send). I also include the exact GUID decoding routine (base64 → binary → Microsoft GUID byte-order swap) your QR format requires.

Quick summary (flow)

  1. Configuration — get devices for a site
    GET https://api.aurelon.com/api/v2/configuration/site/{site}
    (populate device dropdown from Devices[].Name/Devices[].DeviceGUID)

  2. Scan QR (camera or handheld) → decode JobGUID and thumbnail page.

  3. Preview — fetch thumbnail and job details:
    GET https://api.aurelon.com/api/v2/job/{JobGUID}/thumbnail/{page}
    GET https://api.aurelon.com/api/v2/job/{JobGUID} (returns XML)

  4. Send job to device:
    POST https://api.aurelon.com/api/v2/job/{JobGUID}/device/{DeviceGUID}

All API calls must include the MISKey header for authentication.

Base info

  • API base: https://api.aurelon.com/api/v2 (replace if needed)

  • Auth header: MISKey: <your-miskey-value>

  • Content types: Use Accept: application/json for JSON endpoints; for job details use Accept: application/xml if you expect XML.

  • CORS: If building a browser-based UI, ensure the API responds with the appropriate CORS headers for your origin (or run the UI in an environment where the API allows the origin).

1) Configuration — list devices for a Site

Endpoint

Info
GET {API_BASE}/configuration/site/{site}
Header: Accept: application/json
Header: MISKey: <your-miskey>

Purpose
Return configuration records for computers and attached devices at the given site. Use this to populate the printer device selector.

Example response (trimmed)

Info
[
{
"ComputerGUID": "8447e5b0-99ac-11e7-a2d0-215af4f8ef85",
"Name": "MacBookPro",
"Modified": "2018-11-30T19:00:24.977",
"Devices": [
{
"DeviceGUID": "2ac34d2a-62a9-461a-80c9-0015ed333d50",
"DriverID": "1601",
"Modified": "2025-12-09T21:18:06.19",
"Name": "Durst Rhotex 322",
"Queues": [{ "QueueGUID":"...", "Name":"Rhotex Q" }]
},
...
]
}
]

What to extract

  • For each device: Devices[].Name → visible label, Devices[].DeviceGUID → value to store and use for sending the job.

JS example

Info
async function fetchDevices(apiBase, site, MISKey) {
const url = `${apiBase}/configuration/site/${encodeURIComponent(site)}`;
const resp = await fetch(url, { headers: { 'Accept':'application/json', 'MISKey': MISKey }});
if (!resp.ok) throw new Error(`Config fetch failed ${resp.status}`);
return await resp.json(); // parse and extract Devices arrays
}

2) QR decoding details

Your QR contains a URL like: http://pfam.cc/id/01JrqHZorpqUEKJso-CZQZdkw/p1

  • Path /id/01{base64Guid}/{pageToken}

    • 01J prefix indicates a JobGUID. Strip that prefix.

    • {base64Guid} is URL-safe Base64 of the 16-byte binary GUID. Decoding rules (per your environment): replace _/, -+, then append ==, atob()-decode to bytes (16 bytes).

    • The binary follows the Microsoft/Windows GUID storage layout (the first 3 fields are little-endian). You must reorder bytes for textual GUID.

  • {pageToken} like p1 means thumbnail page 1. Default to 1 if absent.

GUID conversion algorithm (JavaScript)
This code decodes the base64 segment and applies the Microsoft GUID byte-order correction:

Info
function decodeBase64GuidToHyphenated(b64seg) {
if (!b64seg) return null;
// apply user rules: '_' -> '/', '-' -> '+', then add '=='
let b64 = b64seg.replace(/_/g,'/').replace(/-/g,'+') + '==';
const bin = atob(b64); // binary string
const bytes = new Uint8Array(bin.length);
for (let i=0;i<bin.length;i++) bytes[i] = bin.charCodeAt(i) & 0xff;
if (bytes.length < 16) { // fallback: return hex
return Array.from(bytes).map(b => ('0'+b.toString(16)).slice(-2)).join('');
}
const hb = b => ('0' + b.toString(16)).slice(-2);
// MS layout -> textual layout
const data1 = hb(bytes[3]) + hb(bytes[2]) + hb(bytes[1]) + hb(bytes[0]);
const data2 = hb(bytes[5]) + hb(bytes[4]);
const data3 = hb(bytes[7]) + hb(bytes[6]);
const data4p1 = hb(bytes[8]) + hb(bytes[9]);
let data4p2 = '';
for (let i = 10; i <= 15; i++) data4p2 += hb(bytes[i]);
return `${data1}-${data2}-${data3}-${data4p1}-${data4p2}`.toLowerCase();
}

Parsing the QR URL

  • Extract path parts.

  • If the segment after /id/ starts with 01J strip 3 chars. Then decode remainder.

  • For page token parse p(\d+) or (\d+) to get page number.

3) Thumbnail fetch

Endpoint

Info
GET {API_BASE}/job/{JobGUID}/thumbnail/{page}
Header: Accept: application/json (or Accept: image/*)
Header: MISKey: <your-miskey>

Behavior / Response

  • The API may return either:

    • Binary image (Content-Type image/png / image/jpeg / application/octet-stream), OR

    • JSON that contains a base64 payload, e.g. { "ThumbnailBase64": "..." } or { "thumbnail": "..." }, OR

    • Possibly an array of objects where first contains ThumbnailBase64 or thumbnail.

  • Display strategy:

    • If Content-Type is image/* (or application/octet-stream) → resp.blob() then URL.createObjectURL(blob) and set <img>.src.

    • If JSON → look for ThumbnailBase64, thumbnailBase64, Thumbnail, thumbnail, or nested data.thumbnail, and set <img>.src = "data:image/png;base64," + b64.

JS example

Info
async function fetchThumbnail(apiBase, jobGuid, page, MISKey) {
const url = `${apiBase}/job/${encodeURIComponent(jobGuid)}/thumbnail/${encodeURIComponent(page)}`;
const resp = await fetch(url, { headers: { 'Accept': 'application/json', 'MISKey': MISKey }});
if (!resp.ok) throw new Error('thumbnail failed ' + resp.status);
const ct = resp.headers.get('Content-Type') || '';
if (ct.includes('application/json')) {
const j = await resp.json();
// get base64 in j.ThumbnailBase64 or j.thumbnail or similar
} else if (ct.startsWith('image/') || ct === 'application/octet-stream') {
const blob = await resp.blob();
return URL.createObjectURL(blob);
} else {
// fallback: try resp.text() and parse JSON
}
}

4) Job details (XML)

Endpoint

Info
GET {API_BASE}/job/{JobGUID}
Header: Accept: application/xml
Header: MISKey: <your-miskey>

Behavior

  • The endpoint returns the job metadata. In your current environment the response is XML, so parse it with DOMParser.

  • Common fields to extract for the job card:

    • Title / JobName / Name / DocumentName / FileName

    • Status / State / JobStatus

    • PageCount / Pages

    • SubmittedBy / User / CreatedBy

    • CreatedAt / SubmittedAt

    • Priority

Parsing strategy

  • Use DOMParser().parseFromString(xml, 'application/xml').

  • Because the XML may have namespaces or different tag names, look for several candidate names (case-insensitive) and search by localName for robustness.

  • If the response is JSON instead of XML, parse JSON.

JS example

Info
function parseJobXml(xmlText) {
const doc = new DOMParser().parseFromString(xmlText, 'application/xml');
if (doc.getElementsByTagName('parsererror').length) throw new Error('XML parse error');
function find(cands) {
cands = cands.map(s => s.toLowerCase());
// try direct element names, then fallback to scanning localName
for (const cand of cands) {
const nodes = doc.getElementsByTagName(cand);
if (nodes && nodes.length && nodes[0].textContent) return nodes[0].textContent.trim();
}
const all = doc.getElementsByTagName('*');
for (const el of all) {
if (el.localName && cands.includes(el.localName.toLowerCase()) && el.textContent) return el.textContent.trim();
}
return null;
}
return {
JobGUID: find(['JobGUID','JobId','GUID','Id','id']),
Title: find(['Title','JobName','Name','DocumentName','FileName']),
Status: find(['Status','State','JobStatus','JobState']),
PageCount: find(['PageCount','Pages','NumberOfPages'])
// etc...
};
}

5) Send a job to a device

Endpoint

Info
POST {API_BASE}/job/{JobGUID}/device/{DeviceGUID}
Header: MISKey: <your-miskey>
Header: Accept: application/json
Body: none (or null) — the API expects POST with path params

Behavior

  • Sends the job to the device identified by DeviceGUID. Returns success JSON or error.

  • Use 200/201 to indicate success. On error, inspect status and body.

JS example

Info
async function sendJobToDevice(apiBase, jobGuid, deviceGuid, MISKey) {
const url = `${apiBase}/job/${encodeURIComponent(jobGuid)}/device/${encodeURIComponent(deviceGuid)}`;
const resp = await fetch(url, { method: 'POST', headers: { 'MISKey': MISKey, 'Accept': 'application/json' }});
if (!resp.ok) {
const txt = await resp.text().catch(()=>null);
throw new Error('Send failed: ' + resp.status + ' ' + txt);
}
return await resp.json().catch(()=>null);
}

Error handling & robustness

  • 401 / 403: MISKey missing/invalid. Show a message to user to check MISKey from Hub (User Profile → Settings → External API).

  • 404 job: JobGUID may be wrong; implement a helpful message.

  • CORS: Browser apps need API CORS headers. If you get network/CORS errors, either run a backend proxy or ensure the API allows your origin.

  • Binary vs JSON thumbnail: handle both; fall back to resp.text() if content-type unknown and attempt JSON parse for base64.

  • GUID decode fallback: If decoded GUID doesn’t correspond to a job, you can optionally try the decoded bytes without the Microsoft swap (or try alternative byte orders) and test by GET /job/{GUID} to see which GUID resolves.

  • Retries: For network instability, retry thumbnail fetch once; for idempotent GETs it’s safe to retry.

Example full flow (JS pseudocode)

Info
async function onScan(scannedText) {
// 1) decode
const decoded = decodeScanResult(scannedText); // decodeScanResult returns {jobGuid, page}
if (!decoded) throw new Error('Could not decode JobGUID');
const { jobGuid, page } = decoded;

// 2) show jobGUID/page
ui.showJobGUID(jobGuid, page);

// 3) fetch thumbnail
try {
const thumbSrc = await fetchThumbnail(API_BASE, jobGuid, page, MISKey);
ui.setThumbnail(thumbSrc);
} catch(e) {
console.warn('thumbnail failed', e);
}

// 4) fetch job details (XML)
const jobXmlText = await fetch(`${API_BASE}/job/${encodeURIComponent(jobGuid)}`, { headers: { 'Accept':'application/xml', 'MISKey': MISKey }});
const jobText = await jobXmlText.text();
const jobObj = parseJobXml(jobText);
ui.showJobCard(jobObj);

// 5) When user clicks "Send"
await sendJobToDevice(API_BASE, jobGuid, deviceGuid, MISKey);
ui.notify('Job sent');
}

Tips, notes & gotchas

  • Where to get MISKey & Site#

    • MISKey → Hub User Profile → Settings → External API.

    • Site# → Hub Account → Sites.

  • Printed QR format

    • Hub job bag prints URLs in the pfam.cc form; ensure your QR generator produces the 01{base64} format as above.

  • Microsoft GUID endianness

    • The first 4 + 2 + 2 bytes are stored little-endian — you must reverse those bytes to produce the canonical textual GUID. The provided decodeBase64GuidToHyphenated implements this.

  • Camera auto-stop

    • In the UI you probably want the camera to stop after the first successful decode to avoid duplicate scans. Stop html5-qrcode on success.


Quick checklist for implementation

  • Implement configuration UI →GET /configuration/site/{site} → populate devices.

  • Implement QR decode function (base64 normalization + MS GUID swap).

  • ImplementGET /job/{GUID}/thumbnail/{page} handling binary & JSON-with-base64.

  • ImplementGET /job/{GUID} with XML parsing.

  • ImplementPOST /job/{GUID}/device/{DeviceGUID} to send job, with MISKey header.

  • PersistAPI_BASE, Site#, MISKey, DeviceGUID (localStorage).

  • Camera scanning (e.g.,html5-qrcode) with default back camera and always auto-stop.

    • Related Articles

    • Job Tracking

      It is possible to track your jobs and the individual images in a nest by accessing the Tracking tab in the Cloud. From here you can preview the nested job & print part labels that can be kept with the job as it travels around your workplace. Lets ...
    • Submit DTG Job via Cloud API

      How to submit a Job via Cloud API to DTG printer General Postman documentation can be found here. This example is specifically for Cloud API Specifications of example Job In this example we use a PMM which has your required "Image Processing" steps ...
    • Summa set-up for Barcode reading

      The steps below describe how to set up the Summa so that the cut jobs in the RIP are picked up automatically by reading the barcode. File preparation - Layout: Create a print and Cut file using e.g. Summa S Class 2 160 D/T - Select the Summa S Class ...
    • DTG Separation Tool

      Using the DTG Separation tool in Editor The DTG Separation tool, accessible in PrintFactory Editor, is crafted to eliminate unnecessary colors from the image. Its purpose is to enable effective printing on colored garments, preventing overinking or ...
    • Job XML Generator for API

      Use this page to build a valid Job.xml for PrintFactory’s Cloud API, without manual math. The tool lets you enter job metadata, define documents, and place imposition parts while a live preview shows how everything fits on the media (with margins). ...