---
title: Quickstart
description: Create your first passport in five minutes — register, mint an API key, post a single passport, scan the QR.
canonical: "https://www.tracepass.eu/docs/quickstart"
locale: en
source: "https://www.tracepass.eu/docs/quickstart"
---

# Quickstart

> Create your first passport in five minutes — register, mint an API key, post a single passport, scan the QR.

Five minutes from signup to a draft Digital Product Passport. This guide ships the smallest possible working example — one product, one passport, no parties, no webhooks. Layer those in once you've seen the round-trip.

## Before you start

You need a TracePass workspace on **any plan, including Free** — v1 API access is on every tier. Only Free (100/day) and Basic (200/day) have a daily call cap; Starter and above are unlimited. Sign up at [app.tracepass.eu/register](https://app.tracepass.eu/register), then come back here. The examples below assume the production base URL `https://app.tracepass.eu`; substitute your own host if you're running self-hosted.

## 1\. Mint an API key

1. Open **Developer → API keys** in the dashboard.
2. Click **New key**, give it a label (“Quickstart” works), and copy the secret. Keys start with the `tp_` prefix followed by an opaque random suffix — store them in your secret manager, not in source control.
3. Every API call carries the key as a Bearer token in the standard`Authorization` header. We'll mask it as`tp_REDACTED_xxxxxxxxxxxx` everywhere below.

## 2\. Create a product

Passports always belong to a product, and a product is bound to a category template that drives field validation, JSON-LD emission, and the public viewer's rendering. Categories are seeded — pick the slug that matches your goods. For batteries it's `batteries`; for textiles, `textiles`; for jewelry, `jewelry`. The full list is in the public Buyer's Guide.

```bash
curl -sS https://app.tracepass.eu/api/v1/products \
  -H "Authorization: Bearer tp_REDACTED_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "48V Li-Ion Pack",
    "model": "BP-48V-100",
    "category": "batteries"
  }'
```

The 201 response includes a `_id` — that's your product handle. Hold onto it for step 3.

## 3\. Create a passport

A passport is one serialised unit of a product. Set `productId` to the product you just created, supply a 14-digit GS1 GTIN (with valid check digit) plus a serial unique within the GTIN. The passport materialises in `draft` status — fields are populated via the per-field PATCH endpoint, then the passport is published from the dashboard once review is complete.

```bash
curl -sS https://app.tracepass.eu/api/v1/passports \
  -H "Authorization: Bearer tp_REDACTED_xxxxxxxxxxxx" \
  -H "Content-Type: application/json" \
  -d '{
    "productId": "6650a1b2c3d4e5f6a7b8c9d0",
    "gs1": {
      "gtin": "04012345000016",
      "serialNumber": "BP-48V-100-000001"
    }
  }'
```

The 201 response carries `gs1.digitalLinkUri` — the GS1 Digital Link URL you can encode into a QR code today, even before the passport is published. Until publish the URL returns a 503 placeholder; after publish it serves the public viewer (HTML by default, `application/ld+json` on content negotiation).

## 4\. Scan the QR

After you've filled out fields and published the passport from the dashboard, open `gs1.digitalLinkUri` in a browser — that's exactly what an end consumer or a regulator's mobile scanner would render. The same URL with `Accept: application/ld+json` returns the JSON-LD document for machine consumers (auditors, EPREL ingestion, the upcoming EU DPP registry).

```bash
curl -sSL https://id.tracepass.eu/p/01/04012345000016/21/BP-48V-100-000001 \
  -H "Accept: application/ld+json"
```

### Where next

You now have one passport. The two follow-ups most teams ship next are: (a) attach economic-operator parties so the regulator's required-roles check passes — see the [Upsert party](/docs/upsert-party) endpoint; (b) wire a webhook so your ERP learns about lifecycle changes (publish, suspend, archive) — see the [Webhooks](/docs/webhooks) section.

**Tip —** Treat every `POST` / `PATCH` / `DELETE` as idempotent by sending an `Idempotency-Key` header with a UUID v4 your client generates per logical operation. The platform replays the original response for 24 hours on the same key, so a network retry is safe.
