---
title: "Fetch one code"
method: GET
path: "/api/v1/codes/{linkId}"
tags: ["Public API v1"]
---

# Fetch one code

`GET /api/v1/codes/{linkId}`

## Request

- Base URL: `https://scanduro.com`
- URL: `https://scanduro.com/api/v1/codes/{linkId}`
- Auth: HTTP bearer

## Response `200`

The code.

- object
  - `data` PublicCode, required: An explicit allowlist of fields, not the stored row. A column added to the database must not silently appear here, because this surface is versioned and anything it returns becomes a compatibility obligation.
    - `shortUrl` string, uri, nullable: Server-derived canonical resolver URL for a live dynamic URL code, including its verified branded hostname where applicable. Null for sandbox, static and non-URL payloads. Integrations must encode this value, not the mutable destination, into dynamic QR artwork.
    - `id` string, required: The immutable public identity of the link. Assigned once, never changed, never reused. Store this, not the slug — a slug can be retired and a domain can be moved.
    - `name` string, required
    - `type` 'static' | 'dynamic', required
    - `kind` 'qr' | 'link', required
    - `contentType` 'url' | 'text' | 'vcard' | 'wifi' | 'email' | 'sms' | 'geo' | 'pdf' | 'gs1', required
    - `slug` string, required
    - `destination` string, required
    - `status` 'active' | 'paused' | 'blocked', required: The product state — whether the owner gets editing and analytics.
    - `hostname` string, nullable: The branded host this code resolves on, or `null` for the shared resolver. Reported rather than left to be inferred: the apex is deployment configuration, so a client that reconstructed the host from the label it sent would get it wrong the moment the apex changed — and this is the URL that gets printed.
    - `mode` 'live' | 'test': Which namespace this row belongs to, decided by the key that created it and never patchable. A `test` row does NOT resolve — that is what makes a free sandbox safe to offer, because a sandbox code cannot be printed and quietly work for a while.
    - `resolverState` 'active' | 'frozen' | 'suspended', required: The infrastructure state — whether the link resolves at all. Read-only here; only an operator changes it. A lapsed subscription never appears in this field.
    - `scanCap` integer, nullable
    - `createdAt` string, date-time, required

## Other responses

- `401`: No key, a malformed key, an unknown key, a revoked key or an expired key. Deliberately one response for all five: telling the caller which applies would make the endpoint an oracle for enumerating valid keys.
- `403`: Either the plan does not include API access (`plan_required`) or the key does not carry the required scope (`missing_scope`). The credential itself is valid in both cases.
- `404`: No such code in this workspace. Another tenant's id reads as absent, not as forbidden.
- `429`: Per-key limit reached. Retry-After gives the seconds remaining in the window.

---

[API](https://skmtc.dev/scanduro/apis/scanduro-public-api.md) · [All operations](https://skmtc.dev/scanduro/apis/scanduro-public-api/llms.txt) · [OpenAPI document](https://skmtc.dev/scanduro/apis/scanduro-public-api/revisions/cdb36d96cad7?raw)
