Skip to main content

Templates

Template endpoints allow you to manage design templates for QR codes and pages.

List Templates

Get a list of templates. There are two endpoints:

  • Public templates: GET https://v1.freeqr.io/api/templates - Returns public templates (visibility = 1)
  • Project templates: GET https://v1.freeqr.io/api/projects/{project}/templates - Returns templates in a specific project

Query Parameters

ParameterTypeRequiredDescription
pageintegerNoPage number (default: 1)
limitintegerNoItems per page (default: 10, max: 100)
sortstringNoSort field (default: order)
filters[type]integerYesFilter by template type (required). Values: 1 (PAGE_DESIGN), 2 (QR_DESIGN)
filters[user_id]stringNoFilter by user ID. Use current to filter by the authenticated user's ID

Filter Behavior

  • Public templates endpoint (GET https://v1.freeqr.io/api/templates): Returns templates with visibility = 1 (PUBLIC). If filters[user_id] is provided, filters by that user. Otherwise, returns all public templates.
  • Project templates endpoint (GET https://v1.freeqr.io/api/projects/{project}/templates): Returns templates for the specified project. If filters[user_id] is provided, further filters by that user.

Response

{
"data": [
{
"id": "01arz3ndektsv4rrffq69g5fav",
"project_id": "01arz3ndektsv4rrffq69g5fav",
"thumbnail_file_id": null,
"name": "My Template",
"description": null,
"type": 2,
"visibility": 1,
"current_version": 1,
"created_at": "2024-01-01T00:00:00.000000Z",
"updated_at": "2024-01-01T00:00:00.000000Z",
"current_template_version": {
"id": "01arz3ndektsv4rrffq69g5fav",
"template_id": "01arz3ndektsv4rrffq69g5fav",
"thumbnail_file_id": null,
"version": 1,
"description": null,
"visibility": 1,
"pending_visibility": null,
"config": {},
"created_at": "2024-01-01T00:00:00.000000Z",
"updated_at": "2024-01-01T00:00:00.000000Z"
}
}
],
"meta": {
"total": 1
},
"included_files": []
}

Note:

  • The type field is an integer enum: 1 = PAGE_DESIGN, 2 = QR_DESIGN.
  • The visibility field is an integer enum: 1 = PUBLIC, 2 = HIDDEN, 3 = PRIVATE.

Create Template

Create a new template in a project.

POST https://v1.freeqr.io/api/projects/{project}/templates

Requires Authentication: Yes

Path Parameters

ParameterTypeRequiredDescription
projectstring (ULID)YesProject ID

Request Body

{
"name": "My Template",
"description": "Template description",
"type": 2,
"template_version": {
"config": {},
"description": "Initial version"
}
}

Parameters

ParameterTypeRequiredDescription
namestringYesTemplate name (max 255 characters)
descriptionstringNoTemplate description (max 1000 characters)
typeintegerYesTemplate type enum: 1 (PAGE_DESIGN), 2 (QR_DESIGN)
template_versionobjectNoOptional template version data
template_version.configobjectNoTemplate version configuration (max 10KB)
template_version.descriptionstringNoTemplate version description

Note:

  • The template is automatically assigned to the authenticated user (user_id is set automatically)
  • Visibility is determined by the project settings, not set directly in the request
  • Maximum 100 templates per user
  • Plan-based limits apply for templates per project

Response

{
"data": {
"id": "01arz3ndektsv4rrffq69g5fav",
"project_id": "01arz3ndektsv4rrffq69g5fav",
"thumbnail_file_id": null,
"name": "My Template",
"description": "Template description",
"type": 2,
"visibility": 1,
"current_version": 1,
"created_at": "2024-01-01T00:00:00.000000Z",
"updated_at": "2024-01-01T00:00:00.000000Z",
"current_template_version": {
"id": "01arz3ndektsv4rrffq69g5fav",
"template_id": "01arz3ndektsv4rrffq69g5fav",
"version": 1,
"config": {},
"description": "Initial version",
"created_at": "2024-01-01T00:00:00.000000Z",
"updated_at": "2024-01-01T00:00:00.000000Z"
}
}
}

Note: If template_version is provided in the request, a version will be created and current_version will be 1. If not provided, current_version will be 0 and current_template_version will be null.

Get Template

Get a specific template by ID.

GET https://v1.freeqr.io/api/templates/{id}

Requires Authentication: Yes

Path Parameters

ParameterTypeRequiredDescription
idstring (ULID)YesTemplate ID

Response

{
"data": {
"id": "01arz3ndektsv4rrffq69g5fav",
"project_id": "01arz3ndektsv4rrffq69g5fav",
"thumbnail_file_id": null,
"name": "My Template",
"description": "Template description",
"type": 2,
"visibility": 1,
"current_version": 0,
"created_at": "2024-01-01T00:00:00.000000Z",
"updated_at": "2024-01-01T00:00:00.000000Z",
"current_template_version": {
"id": "01arz3ndektsv4rrffq69g5fav",
"template_id": "01arz3ndektsv4rrffq69g5fav",
"version": 1,
"config": {},
"description": "Initial version",
"created_at": "2024-01-01T00:00:00.000000Z",
"updated_at": "2024-01-01T00:00:00.000000Z"
}
}
}

Update Template

Update an existing template.

PATCH https://v1.freeqr.io/api/templates/{id}

Requires Authentication: Yes

Path Parameters

ParameterTypeRequiredDescription
idstring (ULID)YesTemplate ID

Request Body

{
"name": "Updated Template",
"description": "Updated description",
"visibility": 3,
"template_version": {
"config": {},
"description": "Updated version"
}
}

Parameters

ParameterTypeRequiredDescription
namestringNoTemplate name (max 255 characters)
descriptionstringNoTemplate description (max 1000 characters)
visibilityintegerNoVisibility enum: 1 (PUBLIC), 2 (HIDDEN), 3 (PRIVATE)
template_versionobjectNoOptional template version data
template_version.configobjectNoTemplate version configuration (max 10KB)
template_version.descriptionstringNoTemplate version description (max 1024 characters)

Update Behavior

Pending Review Workflow:

  • If the template has visibility = 1 (PUBLIC) OR if you're changing the visibility field, the update will be stored in pending_update_data for admin review
  • Updates to templates with existing pending_update_data will be rejected with 409 Conflict error

Immediate Updates:

  • For private templates without visibility changes, updates are applied immediately
  • Template version updates follow the same workflow (draft for public templates, immediate for private)

Response

{
"data": {
"id": "01arz3ndektsv4rrffq69g5fav",
"project_id": "01arz3ndektsv4rrffq69g5fav",
"thumbnail_file_id": "01arz3ndektsv4rrffq69g5fav",
"name": "Updated Template",
"description": "Updated description",
"type": 2,
"visibility": 3,
"current_version": 1,
"pending_update": false,
"pending_update_data": null,
"created_at": "2024-01-01T00:00:00.000000Z",
"updated_at": "2024-01-01T00:00:00.000000Z",
"current_template_version": {
"id": "01arz3ndektsv4rrffq69g5fav",
"template_id": "01arz3ndektsv4rrffq69g5fav",
"version": 1,
"config": {},
"description": "Updated version",
"created_at": "2024-01-01T00:00:00.000000Z",
"updated_at": "2024-01-01T00:00:00.000000Z"
}
}
}

Note: The pending_update and pending_update_data fields are only visible to users with update permissions on the template.

Delete Template

Delete a template.

DELETE https://v1.freeqr.io/api/templates/{id}

Requires Authentication: Yes

Path Parameters

ParameterTypeRequiredDescription
idstring (ULID)YesTemplate ID

Response

Returns the deleted template resource (same structure as Get Template).

List Template Versions

Get all published versions of a template (draft version with version = 0 is excluded).

GET https://v1.freeqr.io/api/templates/{template}/template_versions

Requires Authentication: Yes

Path Parameters

ParameterTypeRequiredDescription
templatestring (ULID)YesTemplate ID

Query Parameters

ParameterTypeRequiredDescription
pageintegerNoPage number (default: 1)
limitintegerNoItems per page (default: 10, max: 100)
sortstringNoSort field (prefix with - for descending)

Note: Results are automatically filtered to only include versions with version > 0 (published versions) and ordered by version descending (newest first).

Response

{
"data": [
{
"id": "01arz3ndektsv4rrffq69g5fav",
"template_id": "01arz3ndektsv4rrffq69g5fav",
"thumbnail_file_id": null,
"version": 2,
"description": "Updated version",
"visibility": 3,
"pending_visibility": null,
"config": {},
"created_at": "2024-01-01T00:00:00.000000Z",
"updated_at": "2024-01-01T00:00:00.000000Z"
},
{
"id": "01arz3ndektsv4rrffq69g5fav",
"template_id": "01arz3ndektsv4rrffq69g5fav",
"thumbnail_file_id": null,
"version": 1,
"description": "Initial version",
"visibility": 3,
"pending_visibility": null,
"config": {},
"created_at": "2024-01-01T00:00:00.000000Z",
"updated_at": "2024-01-01T00:00:00.000000Z"
}
],
"meta": {
"total": 2
},
"included_files": []
}

Note: The visibility field is an integer enum: 1 = PUBLIC, 2 = HIDDEN, 3 = PRIVATE.

Create Template Version

Create a new published version of a template. The version number is automatically assigned (incremented from the current version).

POST https://v1.freeqr.io/api/templates/{template}/template_versions

Requires Authentication: Yes

Path Parameters

ParameterTypeRequiredDescription
templatestring (ULID)YesTemplate ID

Request Body

{
"config": {},
"description": "New version description",
"pending_visibility": 1,
"pending_visibility_review_note": "Requesting public visibility",
"preview": "preview-url"
}

Parameters

ParameterTypeRequiredDescription
configobjectNoTemplate version configuration (max 10KB)
descriptionstringNoVersion description (max 1024 characters)
pending_visibilityintegerNoRequested visibility enum: 1 (PUBLIC), 3 (PRIVATE). Requires admin approval if set to PUBLIC.
pending_visibility_review_notestringNoNote for visibility review
previewstringNoPreview URL (max 255 characters)

Note:

  • If the template has pending_update_data, the request will be rejected with 409 Conflict
  • Version numbers are automatically assigned (incremented from current version)
  • Setting pending_visibility to PUBLIC requires admin approval

Response

{
"data": {
"id": "01arz3ndektsv4rrffq69g5fav",
"template_id": "01arz3ndektsv4rrffq69g5fav",
"thumbnail_file_id": null,
"version": 2,
"description": "New version description",
"visibility": 3,
"pending_visibility": 1,
"config": {},
"created_at": "2024-01-01T00:00:00.000000Z",
"updated_at": "2024-01-01T00:00:00.000000Z"
},
"included_files": []
}

Update Draft Template Version

Update the draft version of a template (version 0). If no draft exists, one will be created automatically.

POST https://v1.freeqr.io/api/templates/{template}/template_versions:draft

Requires Authentication: Yes

Path Parameters

ParameterTypeRequiredDescription
templatestring (ULID)YesTemplate ID

Request Body

{
"config": {},
"description": "Draft description"
}

Parameters

ParameterTypeRequiredDescription
configobjectNoTemplate version configuration (max 10KB)
descriptionstringNoVersion description (max 1024 characters)

Note: The draft version (version 0) is automatically created if it doesn't exist. It has default visibility of PRIVATE (3).

Response

{
"data": {
"id": "01arz3ndektsv4rrffq69g5fav",
"template_id": "01arz3ndektsv4rrffq69g5fav",
"thumbnail_file_id": null,
"version": 0,
"description": "Draft description",
"visibility": 3,
"pending_visibility": null,
"config": {},
"created_at": "2024-01-01T00:00:00.000000Z",
"updated_at": "2024-01-01T00:00:00.000000Z"
},
"included_files": []
}

Get Template Version

Get a specific template version by ID.

GET https://v1.freeqr.io/api/template_versions/{id}

Requires Authentication: Yes

Path Parameters

ParameterTypeRequiredDescription
idstring (ULID)YesTemplate version ID

Response

{
"data": {
"id": "01arz3ndektsv4rrffq69g5fav",
"template_id": "01arz3ndektsv4rrffq69g5fav",
"thumbnail_file_id": null,
"version": 1,
"description": "Version description",
"visibility": 3,
"pending_visibility": null,
"config": {},
"created_at": "2024-01-01T00:00:00.000000Z",
"updated_at": "2024-01-01T00:00:00.000000Z"
},
"included_files": []
}

Note: Draft versions have version = 0. Published versions have version > 0.

Update Template Version

Update an existing template version.

PATCH https://v1.freeqr.io/api/template_versions/{id}

Requires Authentication: Yes

Path Parameters

ParameterTypeRequiredDescription
idstring (ULID)YesTemplate version ID

Request Body

{
"description": "Updated description",
"pending_visibility": 1,
"pending_visibility_review_note": "Requesting public visibility",
"preview": "preview-url"
}

Parameters

ParameterTypeRequiredDescription
descriptionstringNoVersion description (max 1024 characters)
pending_visibilityintegerNoRequested visibility enum: 1 (PUBLIC), 3 (PRIVATE). Requires admin approval if set to PUBLIC.
pending_visibility_review_notestringNoNote for visibility review
previewstringNoPreview URL (max 255 characters)

Note:

  • If the template has pending_update_data, the request will be rejected with 409 Conflict
  • The config field cannot be updated via this endpoint (use the draft endpoint to update config)
  • Setting pending_visibility to PUBLIC requires admin approval

Response

{
"data": {
"id": "01arz3ndektsv4rrffq69g5fav",
"template_id": "01arz3ndektsv4rrffq69g5fav",
"thumbnail_file_id": null,
"version": 1,
"description": "Updated description",
"visibility": 3,
"pending_visibility": 1,
"config": {},
"created_at": "2024-01-01T00:00:00.000000Z",
"updated_at": "2024-01-01T00:00:00.000000Z"
},
"included_files": []
}

Delete Template Version

Delete a template version.

DELETE https://v1.freeqr.io/api/template_versions/{id}

Requires Authentication: Yes

Path Parameters

ParameterTypeRequiredDescription
idstring (ULID)YesTemplate version ID

Note:

  • If the template has pending_update_data, the request will be rejected with 409 Conflict
  • The current template version (the one matching the template's current_version) cannot be deleted and will return 409 Conflict

Response

Returns the deleted template version resource (same structure as Get Template Version).

Restore Template Version

Restore a previous template version by creating a new version from it. This increments the template's current_version and assigns the restored version the next version number.

POST https://v1.freeqr.io/api/template_versions/{id}:restore

Requires Authentication: Yes

Path Parameters

ParameterTypeRequiredDescription
idstring (ULID)YesTemplate version ID

Note:

  • If the template has pending_update_data, the request will be rejected with 409 Conflict
  • Draft versions (version = 0) cannot be restored and will return 400 Bad Request
  • If the version is already the latest version (matches the template's current_version), no changes are made

Response

{
"data": {
"id": "01arz3ndektsv4rrffq69g5fav",
"template_id": "01arz3ndektsv4rrffq69g5fav",
"thumbnail_file_id": null,
"version": 3,
"description": "Restored version",
"visibility": 3,
"pending_visibility": null,
"config": {},
"created_at": "2024-01-01T00:00:00.000000Z",
"updated_at": "2024-01-01T00:00:00.000000Z"
},
"included_files": []
}