# Resolve a label

> Turns a scanned or typed code into the record it identifies, for scanners and bench hardware. xPlant checks, in order: plant labels, explant labels, container labels, then your own plant and explant identifiers — so a code your lab writes on the jar itself, such as LINE-0412, resolves too.

Source: https://docs.xplantpro.com/docs/api/labels/resolve-label

`GET https://app.xplantpro.com/api/v1/labels/resolve`

- Required scope: `read:labels`
- Credentials: workspace API key (`xpk_`)
- Idempotency-Key: ignored on this endpoint

A container code answers with the container and, in `contents`, the items stored at its location.

Looking a code up leaves no trace. To record that someone was at the shelf, also call Record a label scan.

## Query parameters

| Name | Type | Required | Description |
| --- | --- | --- | --- |
| `barcode` | string | Yes | The code exactly as scanned or typed. A plant, explant or container label must match exactly; your own identifiers match ignoring case. |

## Example

**curl**

```bash
curl "https://app.xplantpro.com/api/v1/labels/resolve?barcode=LINE-0412" \
  -H "Authorization: Bearer $XPLANT_API_KEY"
```

**JavaScript**

```js
import { XPlantClient } from "@shmaplex/xplant-sdk";

const client = new XPlantClient({ apiKey: process.env.XPLANT_API_KEY });

const match = await client.labels.resolve("LINE-0412");
console.log(match.record_type, match.display_name, match.url);
```

**Python**

```python
import os
import requests

resp = requests.get(
    "https://app.xplantpro.com/api/v1/labels/resolve",
    headers={"Authorization": f"Bearer {os.environ['XPLANT_API_KEY']}"},
    params={"barcode": "LINE-0412"},
    timeout=10,
)
body = resp.json()
if not body["ok"]:
    raise RuntimeError(f"{resp.status_code} {body['code']}: {body['error']}")
match = body["data"]
```

## Response

`200` with `{ "ok": true, "data": … }`. `data` holds the result.

| Field | Type | Required | Description |
| --- | --- | --- | --- |
| `barcode` | string | Yes | The code that was looked up, trimmed. |
| `record_type` | `"plant"` \| `"explant"` \| `"container"` | Yes | What the code identifies. A `container` is a labelled location — a rack, shelf or box — and resolves to the cultures stored there. |
| `record_id` | string (uuid) | Yes | The plant's, explant's or container's id. |
| `display_name` | string | Yes | A name to show the person scanning: the plant's common name or species, the explant's label or batch number, or the container's label. |
| `url` | string | Yes | Where the record opens in xPlant, as a path on the xPlant web address — for example `/dashboard/explants/<id>`. |
| `contents` | object[] | No | For a container only: the items stored at that location. |
| `contents[].item_id` | string (uuid) | Yes | The stored item's id. |
| `contents[].record_type` | `"plant"` \| `"explant"` \| null | Yes | What the item is, when it is linked to a plant or explant. |
| `contents[].record_id` | string \| null (uuid) | Yes | The plant's or explant's id, when the item is linked to one. |
| `contents[].display_name` | string | Yes | A name to show for the item. |
| `contents[].url` | string \| null | Yes | Where the linked record opens in xPlant, as a path on the xPlant web address. Null when there is no linked record. |

```json title="Response"
{
  "ok": true,
  "data": {
    "barcode": "LINE-0412",
    "record_type": "explant",
    "record_id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d",
    "display_name": "Alocasia LINE-0412",
    "url": "/dashboard/explants/a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d"
  }
}
```

| Response header | Meaning |
| --- | --- |
| `X-Request-Id` | Identifies this request. Include it when you contact support. |

## Errors

| Status | Code | When |
| --- | --- | --- |
| `401` | `UNAUTHORIZED` | The key is missing, malformed or revoked, or its owner is no longer a member of the workspace. |
| `402` | `PAID_PLAN_REQUIRED` | The workspace's plan does not include the API. The full API is included with xPlant+ Teams and Enterprise; on Hobby and Pro Lab, keys can connect devices only. |
| `403` | `FORBIDDEN` | The key lacks a scope this operation requires, or its owner's current role in the workspace cannot use it — a key never does more than its owner can in xPlant. `error` names the scope, and for a role, the role it needs. |
| `403` | `DEVICE_TOKEN_NOT_ACCEPTED` | A device token was sent; this operation needs a workspace API key. |
| `404` | `NOT_FOUND` | Nothing in this workspace matches the code. |
| `422` | `VALIDATION_ERROR` | `barcode` is missing or blank. `error` names it: `barcode: barcode is required`. |
| `429` | `RATE_LIMIT_EXCEEDED` | Too many requests for this key, device token or workspace. Wait `Retry-After` seconds. |
| `500` | `LINK_QUERY_FAILED` | The code could not be looked up. Retry later. |

Branch on `code`, never on the `error` text. See [Errors](https://docs.xplantpro.com/docs/errors.md).
