QR codes and deep links

Open a form in the mobile app from a printed QR code, with fields already filled in — the URL format, where to find each value, and what works offline.

Updated 2026-08-05

A link in the FieldScroll format opens the mobile app, jumps straight to one form, and can fill in fields before the person starts. Printed as a QR code and stuck on a machine, a vehicle, or a door, it turns "find the right form, then type the asset details" into a single scan.

FieldScroll does not generate these codes for you. You build the URL from the format below and encode it with whatever QR tool you already use, which means you can produce one code or ten thousand from your own data.

The URL format

fieldscroll://forms/<form_identifier>?o=<organization_id>&v=1

Three required parts:

PartWhat it is
forms/<form_identifier>The form to open, by its identifier — not its name
oThe organization the form belongs to
vFormat version. Always 1 today

A working example:

fieldscroll://forms/equipment_inspection?o=7c2f0a1e-4b13-4f7a-9c21-0d3e5a91b2e1&v=1

That code opens the Equipment Inspection form, empty, ready to fill in.

The scheme is specific to your app

fieldscroll:// works for the FieldScroll app. If you run FieldScroll under your own brand, your app registers its own scheme and your codes use that instead. A code printed for one branded app does nothing in another — they are separate apps on the device.

Filling fields in advance

Add p.<field_id>=<value> for each field you want filled:

fieldscroll://forms/equipment_inspection?o=7c2f0a1e-…&v=1&p.make=Caterpillar&p.model=320D

Values must be URL-encoded — a space becomes %20, an ampersand becomes %26.

Four field types can be filled this way:

TypeValue to send
TextThe text
NumberThe number
Choice listThe exact option label, for single-answer lists only
Date and timeAn ISO 8601 timestamp, such as 2026-08-05T14:30:00Z

Anything else is ignored: photos, files, signatures, locations, tables, and lookups. Multi-answer choice lists are ignored too, because the format carries one value per field and filling in only the first answer would be misleading.

Values for fields that are not on the form are dropped. This matters when a form changes: if someone renames a field after you print labels, that field stops being filled and the rest of the code keeps working.

Keep codes short

Long URLs make dense QR codes that scan badly, especially on a scuffed label under bad light. Aim to stay under about 220 characters. Three or four short values is a comfortable ceiling.

Linking a code to a specific asset

If the thing you are labelling already exists as a row in a data source — a vehicle, a store, a piece of equipment — link the code to that row instead of repeating its details:

fieldscroll://forms/site_visit?o=7c2f0a1e-…&v=1&r=site:5a8b9c12-3d4e-4f50-a1b2-c3d4e5f60789

The r value is <lookup_field_id>:<row_id>. On scan, the app finds that row in its local copy of the data source and fills the lookup field with it — every column at once, exactly as if the person had searched and picked it.

This is the better option whenever it applies. The URL stays short no matter how many columns the row has, and when the row changes in FieldScroll, the next scan of an already-printed code fills in the new values — nothing has to be reprinted.

Records already submitted do not change. A record keeps the snapshot of the row as it was when that record was captured, exactly as when someone picks the row by hand. See data sources.

It also works with no signal. The row comes from the copy already on the device, so a scan in a basement or a field works the same as one in the office.

That depends on one setting. The row is only found locally, so the data source must be marked for mobile sync and must have reached the device at least once. A source that is not synced to mobile — a reference table used only in the dashboard — cannot be linked to this way, and the form will open without the row. See data sources for that setting.

You can combine both: &r=site:5a8b…&p.visit_type=preventive.

Where to find each value

ValueWhere it is
form_identifierOn the form's page in the dashboard, under Form identifier
organization_idIn the address bar on the organization's page: /organizations/<id>
Row id for r=Not shown in the dashboard — see below

Row ids come from the API rather than the dashboard:

GET /api/v1/organizations/{organization_id}/data-sources/{data_source_id}/rows

Each row in the response carries the id to use in r=. See Authentication for API keys. The same data is available through the MCP server as get_data_source_rows, which is a quick way to pull ids without writing code.

If you are labelling many assets at once, this is also the practical path: export the rows, generate one URL per row, and hand the list to your label printer.

What happens when a code cannot be used

The app explains rather than failing quietly:

  • Wrong organization. The code names an organization the person is not currently in. The app says so and points at the organization switcher in Account.
  • Unknown form. No form on the device matches that identifier — usually it is unpublished, not assigned to that person, or not synced yet.
  • Missing asset row. The form still opens, without the linked row, and the app says the data source needs to sync.
  • Signed out. The app holds the scan, asks the person to sign in, and opens the form once they are in. Nothing is lost, and they do not have to scan again.

One case has no in-app answer: a phone without FieldScroll installed does nothing when it scans the code. A custom link needs the app to be there. If your codes will be scanned by people who might not have it yet, print a line of text on the label telling them what to install.

Things worth knowing

Every scan starts a new entry. A code never reopens an existing one, so scanning the same label twice gives two separate records. Filled-in values do not count as the person having started work — if they scan and back out without typing anything, nothing is kept.

Codes always open the live form, never a draft you are still testing in the builder.

The link is not a key. It carries no permission. Whoever scans it sees the form only if they already have access, and the usual rules decide what they can do. A code that leaves your site gives away nothing beyond a form identifier.

Test before you print. Build one URL, encode it, scan it with a real phone, and confirm the right fields are filled. Field ids and option labels are easy to mistype, and a thousand printed labels is a slow way to find out.