qr-codes

9 endpoints.

GET/api/qr-codes Bearer token

List QR codes

Lists the QR codes the caller's qr-codes:read scope covers, newest first, each with its current target resolved, optionally filtered to one organization or one owning department within it.

Parameters

NameInTypeRequiredDescription
orgquerystringnoOrganization UUID id or slug to filter by (and to resolve slug refs in).
departmentquerystringnoDepartment UUID id or slug, resolved within org (which is then required).
include_archivedquerystringnoInclude archived rows. Defaults to false.

Responses

StatusDescriptionBody
200The visible QR codes.QrCodeList
400The department filter was given without an org filter.ErrorResponse
401The access token is missing or invalid.ErrorResponse
404No visible organization has that id or slug, or the department is not one of the organization's own.ErrorResponse
500The database could not be read.ErrorResponse
POST/api/qr-codes Bearer token

Create a QR code

Creates a QR code — owned by the organization, or by the owning department named within it — pointing at one of the organization's job aids, SCORM courses or quizzes, or at a raw URL. The slug is the public URL segment the image encodes (/qr/{slug}); choose one or have one generated, and print it knowing it never changes — the target does, through PUT /qr-codes/{qr_code_id}/target. Requires qr-codes:write over that owner.

Request body

application/jsonrequiredCreateQrCodeRequest
FieldTypeRequiredDescription
orgstringyes

Organization UUID id or slug the code belongs to.

at least 1 character

departmentstringno

UUID id or slug of the owning department within the organization; omit for a code owned by the organization directly. Ownership scopes administration and, for a url code, limits following it to the department's role holders.

at least 1 character

slugstringno

Omit to have one generated. Choose it before printing: it cannot be changed after.

2–128 characters · matches ^[a-z0-9][a-z0-9_-]{1,127}$

namestringyes

1–200 characters

descriptionstringno

Omit or send empty for no note.

at most 2000 characters

target_kindstringyes

What the code points at: one of this deployment's job aids, hosted SCORM courses or quizzes — reached on the learner's own page for it — or a raw http(s) URL anywhere.

one of "job_aid" | "scorm_course" | "quiz" | "url"

target_idstring (uuid)no

For a job_aid, scorm_course or quiz code: the id of that resource, which must belong to the code's organization. Omit for a url code.

target_urlstring (uri)no

For a url code: where it points. Omit for every other kind.

1–2000 characters

Responses

StatusDescriptionBody
201The created QR code.QrCode
400The request body failed validation.ErrorResponse
401The access token is missing or invalid.ErrorResponse
403The caller does not hold qr-codes:write over the intended owner.ErrorResponse
404No visible organization has that id or slug, or the department or the target resource is not the organization's own.ErrorResponse
409Another QR code already has that slug.ErrorResponse
500The database could not be reached, or the write failed.ErrorResponse
PUT/api/qr-codes/{qr_code_id}/target Bearer token

Point a QR code at a new destination

Replaces where the code leads — one of the organization's job aids, SCORM courses or quizzes, or a raw URL — without changing the printed code. The previous target is logged with the label it has now, readable at GET /qr-codes/{qr_code_id}/target-changes. Requires qr-codes:write over the code's owner.

Parameters

NameInTypeRequiredDescription
qr_code_idpathstring (uuid)yesUUID id of the QR code.

Request body

application/jsonrequiredRetargetQrCodeRequest
FieldTypeRequiredDescription
target_kindstringyes

What the code points at: one of this deployment's job aids, hosted SCORM courses or quizzes — reached on the learner's own page for it — or a raw http(s) URL anywhere.

one of "job_aid" | "scorm_course" | "quiz" | "url"

target_idstring (uuid)no

For a job_aid, scorm_course or quiz code: the id of that resource, which must belong to the code's organization. Omit for a url code.

target_urlstring (uri)no

For a url code: where it points. Omit for every other kind.

1–2000 characters

Responses

StatusDescriptionBody
200The QR code with its new target.QrCode
400The request body failed validation.ErrorResponse
401The access token is missing or invalid.ErrorResponse
403The caller does not hold qr-codes:write over the code's owner.ErrorResponse
404No visible QR code has that id, or the target resource is not the code's organization's own.ErrorResponse
500The database could not be reached, or the write failed.ErrorResponse
GET/api/qr-codes/{qr_code_id}/target-changes Bearer token

Read where a QR code has pointed

Every retarget of the code, most recent first: who changed it and when, and the target before and after with the labels they carried at the time. The code's creation is not a change; the oldest entry's `from` is the target it was created with. Requires qr-codes:read over the code's owner.

Parameters

NameInTypeRequiredDescription
qr_code_idpathstring (uuid)yesUUID id of the QR code.

Responses

StatusDescriptionBody
200The code's target history.QrCodeTargetChangeList
401The access token is missing or invalid.ErrorResponse
404No visible QR code has that id.ErrorResponse
500The database could not be read.ErrorResponse
GET/api/qr-codes/{qr_code_id}/analytics Bearer token

Read who has scanned a QR code

Every recorded scan of the code, folded per person: how many times each scanned it, how many of those went through, and when first and last — with the totals by outcome. Scans are recorded only for signed-in people; a scanner who never signs in is not counted. Requires qr-codes:read over the code's owner.

Parameters

NameInTypeRequiredDescription
qr_code_idpathstring (uuid)yesUUID id of the QR code.

Responses

StatusDescriptionBody
200The code's scan analytics.QrCodeAnalytics
401The access token is missing or invalid.ErrorResponse
404No visible QR code has that id.ErrorResponse
500The database could not be read.ErrorResponse
GET/api/qr-codes/{qr_code_id}/permanent-deletion Bearer token

Preview permanently deleting a QR code

Counts everything DELETE on this path would remove: every recorded scan and every logged destination change. Nothing is changed. Requires qr-codes:delete over the code's owner — a grant separate from qr-codes:write, which only archives.

Parameters

NameInTypeRequiredDescription
qr_code_idpathstring (uuid)yesUUID id of the QR code.

Responses

StatusDescriptionBody
200What the deletion would take with it.DeletionImpact
401The access token is missing or invalid.ErrorResponse
403The caller does not hold qr-codes:delete over the code's owner.ErrorResponse
404No visible QR code has that id.ErrorResponse
500The database could not be read.ErrorResponse
DELETE/api/qr-codes/{qr_code_id}/permanent-deletion Bearer token

Permanently delete a QR code

Hard-deletes the QR code — unlike archiving, which only makes scans answer unavailable. Every recorded scan and every logged destination change goes with it, and the printed code answers 404 from then on. Irreversible. Preview the cost with GET first. Requires qr-codes:delete over the code's owner — a grant separate from qr-codes:write.

Parameters

NameInTypeRequiredDescription
qr_code_idpathstring (uuid)yesUUID id of the QR code.

Responses

StatusDescriptionBody
204The QR code, its scans and its history are gone.—
401The access token is missing or invalid.ErrorResponse
403The caller does not hold qr-codes:delete over the code's owner.ErrorResponse
404No visible QR code has that id.ErrorResponse
500The database could not be reached, or the write failed.ErrorResponse
GET/api/qr-codes/{qr_code_id} Bearer token

Read one QR code

Reads one QR code with its current target resolved — the resource's name and whether a scan can reach it right now. Requires qr-codes:read over the code's owner; the public redirect at /qr/{slug} is a page, not part of this API.

Parameters

NameInTypeRequiredDescription
qr_code_idpathstring (uuid)yesUUID id of the QR code.

Responses

StatusDescriptionBody
200The QR code.QrCode
401The access token is missing or invalid.ErrorResponse
404No visible QR code has that id.ErrorResponse
500The database could not be read.ErrorResponse
PATCH/api/qr-codes/{qr_code_id} Bearer token

Edit or archive a QR code

Changes a QR code's name or note, or archives/restores it — an archived code answers unavailable to every scan while its history stays. The slug never changes; the target changes through PUT /qr-codes/{qr_code_id}/target. Requires qr-codes:write over the code's owner.

Parameters

NameInTypeRequiredDescription
qr_code_idpathstring (uuid)yesUUID id of the QR code.

Request body

application/jsonrequiredUpdateQrCodeRequest
FieldTypeRequiredDescription
namestringno

1–200 characters

descriptionstring | nullno

Send null or empty to clear the note.

at most 2000 characters

archivedbooleanno

True archives the code (every scan answers unavailable); false restores it. Nothing about a printed code changes.

Responses

StatusDescriptionBody
200The updated QR code.QrCode
400The request body failed validation.ErrorResponse
401The access token is missing or invalid.ErrorResponse
403The caller does not hold qr-codes:write over the code's owner.ErrorResponse
404No visible QR code has that id.ErrorResponse
500The database could not be reached, or the write failed.ErrorResponse