Passports

A passport — a digital product passport (DPP) — is one product data record at a level of an ontology. Every passport has a globally unique id, a path within its ontology, optional property values, and a publish_status that can be set explicitly or inherited from its ancestors. Passports are addressed two ways: by their universal id, or by their path.

The passport model

  • Name
    object
    Type
    string
    Description

    Always passport.

  • Name
    id
    Type
    string
    Description

    Unique, universal identifier, e.g. pass_00a1b2c3d4e5f607. Resolves any passport at any depth via GET /v1/passports/:id.

  • Name
    ontology
    Type
    string
    Description

    The id of the ontology this passport belongs to. Nullable.

  • Name
    parent
    Type
    string
    Description

    The parent passport's id. null for the root.

  • Name
    level
    Type
    string
    Description

    The level key this passport sits at (e.g. A, B). Nullable.

  • Name
    path
    Type
    string
    Description

    The passport's position within the ontology: the level key alone for the root (A), otherwise LEVEL:snowflake[/snowflake]. The snowflake segments are bare — no pass_ prefix — and a path read off one response is a valid ?path= argument on the next. Encoded as the TPPMP sort key, e.g. B:07c9…. Nullable.

  • Name
    friendly_id
    Type
    string
    Description

    Optional human-readable alias, unique within the parent. Nullable.

  • Name
    publish_status
    Type
    string
    Description

    The explicit status: published, draft, or archived. null means it inherits from the parent chain.

  • Name
    publish_status_resolved
    Type
    string
    Description

    The effective status after inheritance (present on detail reads only).

  • Name
    values
    Type
    object
    Description

    Property values, keyed by the ontology's property ids. Always a JSON object — {} when the passport has no values yet, never [] — so the field's type never changes with its contents.

  • Name
    ontology_version
    Type
    integer
    Description

    The ontology version this passport is pinned to — the one it was created under. Reads render against this version's levels, and writes validate against its property definitions.

  • Name
    metadata
    Type
    object
    Description

    Caller-owned metadata bag. Always present, {} when empty.

  • Name
    created_at
    Type
    string
    Description

    ISO 8601 timestamp of creation.

  • Name
    updated_at
    Type
    string
    Description

    ISO 8601 timestamp of the last update.

Detail reads

A full detail read (GET /v1/passports/:id and the find endpoint) also includes traversal info:

  • Name
    discoverable_levels
    Type
    array
    Description

    The child levels reachable from this passport when rendering its public page.

  • Name
    discovery_chain
    Type
    array
    Description

    The level traversal used to assemble the full passport.


GET/v1/ontologies/:ontology/passports

List passports at a path

Lists — or searches — the passports under a path within an ontology. Paths start with the level key: B lists the series at level B; deeper paths address a specific branch. Returns a paginated list. Requires passports:read.

Required attributes

  • Name
    path
    Type
    string
    Description

    The path to list under, e.g. B.

Optional attributes

  • Name
    search
    Type
    string
    Description

    Free-text search within the level (up to 100 characters).

  • Name
    limit
    Type
    integer
    Description

    Page size, 1–100 (default 10).

  • Name
    cursor
    Type
    string
    Description

    A pagination cursor from a previous response's next_cursor.

Request

GET
/v1/ontologies/:ontology/passports
curl -G https://api.synexcloud.com/v1/ontologies/ontology_00a1b2c3d4e5f607/passports \
  -H "Authorization: Bearer $SYNEX_API_KEY" \
  -d path=B \
  -d limit=10

Response

{
  "object": "list",
  "data": [
    {
      "object": "passport",
      "id": "pass_11b2c3d4e5f60718",
      "ontology": "ontology_00a1b2c3d4e5f607",
      "parent": "pass_00a1b2c3d4e5f607",
      "level": "B",
      "path": "B:07c9f2a1b3d4e5f6",
      "friendly_id": "PACK-001",
      "publish_status": "published",
      "values": { "property_9f2k7d": "4500" },
      "created_at": "2026-07-12T09:35:00Z",
      "updated_at": "2026-07-12T09:40:00Z"
    }
  ],
  "has_more": false,
  "next_cursor": null,
  "url": "/v1/ontologies/ontology_00a1b2c3d4e5f607/passports"
}

POST/v1/ontologies/:ontology/passports

Create a passport

Creates a passport at a level of the ontology, under a parent passport — start from the ontology's root_passport. singular levels allow one passport per parent (a second fails with 409 passport_exists_at_level); series and many levels allow any number. You never create level A — the root passport is created with the ontology, and trying to create it under a parent is a 400 parameter_invalid on level. The parent must also sit at the level the ontology declares as level's parent: you can't skip a level (creating C directly under an A) or hang a passport off the wrong branch — a mismatch is a 400 parameter_invalid on parent, and nothing is written. Requires passports:write. Accepts an optional Idempotency-Key header.

Required attributes

  • Name
    parent
    Type
    string
    Description

    The parent passport's id.

  • Name
    level
    Type
    string
    Description

    The level key to create at (e.g. B).

Optional attributes

  • Name
    friendly_id
    Type
    string
    Description

    Human-readable alias, unique within the parent (409 friendly_id_taken otherwise).

Request

POST
/v1/ontologies/:ontology/passports
curl https://api.synexcloud.com/v1/ontologies/ontology_00a1b2c3d4e5f607/passports \
  -H "Authorization: Bearer $SYNEX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "parent": "pass_00a1b2c3d4e5f607", "level": "B", "friendly_id": "PACK-001" }'

Response

{
  "object": "passport",
  "id": "pass_11b2c3d4e5f60718",
  "ontology": "ontology_00a1b2c3d4e5f607",
  "parent": "pass_00a1b2c3d4e5f607",
  "level": "B",
  "path": "B:07c9f2a1b3d4e5f6",
  "friendly_id": "PACK-001",
  "publish_status": null,
  "values": {},
  "created_at": "2026-07-12T09:35:00Z",
  "updated_at": "2026-07-12T09:35:00Z"
}

GET/v1/ontologies/:ontology/passports/find

Find a passport by path

Returns the single passport at an exact path, with full traversal detail. Use this when you know a passport's position (e.g. the root at path A) rather than its id. Requires passports:read.

Required attributes

  • Name
    path
    Type
    string
    Description

    The exact path, e.g. A for the root.

Request

GET
/v1/ontologies/:ontology/passports/find
curl -G https://api.synexcloud.com/v1/ontologies/ontology_00a1b2c3d4e5f607/passports/find \
  -H "Authorization: Bearer $SYNEX_API_KEY" \
  -d path=A

Response

{
  "object": "passport",
  "id": "pass_00a1b2c3d4e5f607",
  "ontology": "ontology_00a1b2c3d4e5f607",
  "parent": null,
  "level": "A",
  "path": "A",
  "friendly_id": null,
  "publish_status": "published",
  "publish_status_resolved": "published",
  "values": { "property_11a0f3": "EV-PACK-48V" },
  "discoverable_levels": ["B"],
  "discovery_chain": [{ "level": "A", "type": "singular" }],
  "created_at": "2026-07-10T12:00:00Z",
  "updated_at": "2026-07-12T09:40:00Z"
}

GET/v1/passports/:id

Retrieve a passport

Retrieves a passport by its universal id — this works for any passport at any depth, without knowing its ontology or path. It's a full detail read: values (file and image values carry short-lived download links), the resolved publish status, and traversal info. Requires passports:read.

Request

GET
/v1/passports/pass_11b2c3d4e5f60718
curl https://api.synexcloud.com/v1/passports/pass_11b2c3d4e5f60718 \
  -H "Authorization: Bearer $SYNEX_API_KEY"

Response

{
  "object": "passport",
  "id": "pass_11b2c3d4e5f60718",
  "ontology": "ontology_00a1b2c3d4e5f607",
  "parent": "pass_00a1b2c3d4e5f607",
  "level": "B",
  "path": "B:07c9f2a1b3d4e5f6",
  "friendly_id": "PACK-001",
  "publish_status": "published",
  "publish_status_resolved": "published",
  "values": {
    "property_9f2k7d": "4500",
    "property_datasheet": { "url": "https://files.synexcloud.com/...", "expires_at": "2026-07-12T10:10:00Z" }
  },
  "discoverable_levels": ["C"],
  "discovery_chain": [
    { "level": "B", "type": "series" },
    { "level": "C", "type": "many" }
  ],
  "created_at": "2026-07-12T09:35:00Z",
  "updated_at": "2026-07-12T09:40:00Z"
}

PATCH/v1/passports/:id

Update a passport

Updates any combination of property values, friendly_id, and publish_status in one call. All values are validated against the ontology's property definitions before anything is written — a single bad value fails the whole values group with 400 value_invalid and per-property errors; valid values are then applied. Every change writes an audit event. Requires passports:write.

Optional attributes

  • Name
    values
    Type
    object
    Description

    A map of property id → new raw value.

  • Name
    friendly_id
    Type
    string
    Description

    A new human-readable alias, unique within the parent.

  • Name
    publish_status
    Type
    string
    Description

    published, draft, archived, or automatic. Setting automatic clears the explicit status so the passport inherits again.

Request

PATCH
/v1/passports/pass_11b2c3d4e5f60718
curl -X PATCH https://api.synexcloud.com/v1/passports/pass_11b2c3d4e5f60718 \
  -H "Authorization: Bearer $SYNEX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "values": { "property_9f2k7d": 4500, "property_material": "Graphite" },
    "friendly_id": "PACK-001-R2",
    "publish_status": "published"
  }'

Response

{
  "object": "passport",
  "id": "pass_11b2c3d4e5f60718",
  "ontology": "ontology_00a1b2c3d4e5f607",
  "level": "B",
  "path": "B:07c9f2a1b3d4e5f6",
  "friendly_id": "PACK-001-R2",
  "publish_status": "published",
  "values": { "property_9f2k7d": 4500, "property_material": "Graphite" },
  "updated_at": "2026-07-12T09:45:00Z"
}

Dates

A date value is stored as the calendar day it names, always normalized to YYYY-MM-DD. The response echoes back that canonical form — a different string than you sent whenever you write another spelling — which is what keeps dates sortable and comparable with PassQL >, <, and between.

Accepted on write: 2026-07-22, 2026/07/22, 22 Jul 2026, July 22, 2026, 20260722, and ISO 8601 datetimes such as 2026-07-22T10:30:00Z (truncated to the day they name, with no timezone shift).

Rejected with 400 value_invalid / invalid_date: days that don't exist (2026-02-30, 2026-02-29), years outside four digits (99999-01-01), and relative expressions (next tuesday, tomorrow, +1 day) — a value whose meaning changes every time it's read is not a date.

Numeric dates are never guessed at

Whether 03/04/2026 means 3 April or 4 March is a fact about the writer's locale, not about the string, so the API refuses to pick one. A separator-delimited numeric date is rejected with 400 ambiguous_date whenever both readings are real days:

SentStoredWhy
13/05/20262026-05-13only day-first is a real date
05/13/20262026-05-13only month-first is a real date
03/03/20262026-03-03both readings agree
03/04/2026400 ambiguous_date3 April and 4 March are both real

The same applies to - and . separators. Send YYYY-MM-DD and none of this applies to you.


DELETE/v1/passports/:id

Delete a passport

Deletes the passport and releases its friendly_id for reuse within the parent. Requires passports:write.

Request

DELETE
/v1/passports/pass_11b2c3d4e5f60718
curl -X DELETE https://api.synexcloud.com/v1/passports/pass_11b2c3d4e5f60718 \
  -H "Authorization: Bearer $SYNEX_API_KEY"

Response

{
  "object": "passport",
  "id": "pass_11b2c3d4e5f60718",
  "deleted": true
}

GET/v1/passports/:id/qr

Download a passport's QR code

Renders the QR code linking to the passport's public page — the same link the Synex app prints. Returns binary image data, so write it straight to a file. Requires passports:read.

Optional attributes

  • Name
    format
    Type
    string
    Description

    png (default), jpg, svg, or pdf.

  • Name
    size
    Type
    integer
    Description

    Pixel size, 64–2048 (default 512). A value outside that range is rejected with 400 parameter_invalid rather than clamped.

Request

GET
/v1/passports/:id/qr
curl -G https://api.synexcloud.com/v1/passports/pass_11b2c3d4e5f60718/qr \
  -H "Authorization: Bearer $SYNEX_API_KEY" \
  -d format=png \
  -d size=1024 \
  -o passport-qr.png

Response

HTTP/1.1 200 OK
Content-Type: image/png

(binary QR image — PNG, JPG, SVG, or PDF per the `format` parameter)

Was this page helpful?