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, property values, and a publish_status that is either set explicitly or inherited from its ancestors — except released, which a passport only ever has explicitly. 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_3e9a1c5b7d2f4083. 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:3e9a1c5b7d2f4083. Nullable.

  • Name
    friendly_id
    Type
    string
    Description

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

  • 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
    publish_status
    Type
    string
    Description

    The explicit status: released, draft, or archived. null means it inherits from the parent chain — but released is never inherited.

  • Name
    publish_status_resolved
    Type
    string
    Description

    The effective status after inheritance, on every read: released, draft, or archived, never null. A passport with no explicit status under a released ancestor resolves to draft.

  • Name
    release_number
    Type
    integer
    Description

    How many times the passport has been released, 0 if never. It survives an un-release, so a re-release is number 2.

  • Name
    values
    Type
    object
    Description

    Property values keyed by the ontology's property ids, each wrapped in a value envelope (see below). Always a JSON object — {} when the passport has no values yet, never [] — so the field's type never changes with its contents.

  • 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.

Values

Writes take a flat map of property id → value; reads wrap every property in an envelope:

values on a read

{
  "values": {
    "property_capacity": { "value": 78.4 },
    "property_serial": { "value": "KES-EVP-24-0917", "language": "en", "is_fallback": false }
  }
}

Translatable types — short_text, long_text, tags, and file — carry language and is_fallback beside value; see Translated values. On a full read, a file or image value carries a short-lived download link inside value, next to its filename, extension, and size; list rows and the PATCH response return the stored file reference without a link.

There is no chart property type: charts are a section of the ontology's composition that plots ordinary numeric values.

Full reads

GET /v1/passports/:id and the find endpoint return the full shape, which adds:

  • Name
    discoverable_levels
    Type
    array
    Description

    The adjacent level keys the public passport traverses to from this one — its singular and many children, plus its parent unless it is the root.

  • Name
    discovery_chain
    Type
    array
    Description

    Every level key reachable from this one, in depth order — the traversal used to assemble the full passport.

  • Name
    granularity
    Type
    object
    Description

    Which passports this one reports as to the EU registry — see below.

List rows, and the response to a PATCH that changed something, omit these three fields.

Reported granularity

  • Name
    tier
    Type
    string
    Description

    The tier this passport's level reports as — model, batch, or item — or null when the level is internal only.

  • Name
    model, batch, item
    Type
    string
    Description

    For each tier, the id of the nearest passport — this one or an ancestor — at the level marked is_core for that tier. null when there is none on the way up, which includes every tier below this passport: resolution is upward only, and "every item in this batch" is a list query.

Levels declare their granularity and is_core on the ontology. If the EV Battery Pack ontology reported its product line as model, its packs as batch, and its cells as item, each level its tier's core, a cell would read:

granularity on a cell

{
  "granularity": {
    "tier": "item",
    "model": "pass_5f0c8b3a6d1e4072",
    "batch": "pass_3e9a1c5b7d2f4083",
    "item": "pass_9c4e7a1d5b3f2064"
  }
}

The block resolves against the ontology version the passport is pinned to. Resolving it costs one read per level, which is why list rows don't carry it.


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 passports at level B; deeper paths address a specific branch. Returns a paginated list of passports without the full-read fields. Requires passports:read.

Required attributes

  • Name
    path
    Type
    string
    Description

    The path to list under, e.g. B, or a branch such as C:3e9a1c5b7d2f4083.

Optional attributes

  • Name
    search
    Type
    string
    Description

    Case-insensitive substring match on a passport's friendly_id or id — not its name (up to 100 characters). Matching is a bounded scan, so a page can come back short, or empty, while has_more is still true: keep following next_cursor before concluding nothing matches.

  • Name
    lang
    Type
    string
    Description

    The language to read translated values in, or all.

  • 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_7d1f4a2b9c3e5081/passports \
  -H "Authorization: Bearer $SYNEX_API_KEY" \
  -d path=B \
  -d limit=10

Response

{
  "object": "list",
  "data": [
    {
      "object": "passport",
      "id": "pass_3e9a1c5b7d2f4083",
      "ontology": "ontology_7d1f4a2b9c3e5081",
      "parent": "pass_5f0c8b3a6d1e4072",
      "level": "B",
      "path": "B:3e9a1c5b7d2f4083",
      "friendly_id": "PACK-24-0917",
      "ontology_version": 2,
      "publish_status": "released",
      "publish_status_resolved": "released",
      "release_number": 1,
      "values": {
        "property_capacity": { "value": 78.4 },
        "property_serial": { "value": "KES-EVP-24-0917", "language": "en", "is_fallback": false }
      },
      "metadata": { "batch_ref": "BATCH-2026-07" },
      "created_at": "2026-07-22T14:10:43Z",
      "updated_at": "2026-07-22T14:18:02Z"
    },
    {
      "object": "passport",
      "id": "pass_6b2d4f8a0c1e7359",
      "ontology": "ontology_7d1f4a2b9c3e5081",
      "parent": "pass_5f0c8b3a6d1e4072",
      "level": "B",
      "path": "B:6b2d4f8a0c1e7359",
      "friendly_id": "PACK-24-0918",
      "ontology_version": 2,
      "publish_status": null,
      "publish_status_resolved": "draft",
      "release_number": 0,
      "values": {
        "property_capacity": { "value": 77.9 },
        "property_serial": { "value": "KES-EVP-24-0918", "language": "en", "is_fallback": false }
      },
      "metadata": {},
      "created_at": "2026-07-22T14:11:09Z",
      "updated_at": "2026-07-22T14:11:09Z"
    }
  ],
  "has_more": true,
  "next_cursor": "WyJvbnRvbG9neV83ZDFmNGEyYjljM2U1MDgxIl0",
  "url": "/v1/ontologies/ontology_7d1f4a2b9c3e5081/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.

A team without a company — a supplier team — can't issue passports and is refused with 403 company_required. A create under an ontology with a passport transfer running is refused with 409 ontology_locked (see the note on Update a passport).

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).

  • Name
    metadata
    Type
    object
    Description

    Your own metadata for the new passport.

Request

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

Response

{
  "object": "passport",
  "id": "pass_3e9a1c5b7d2f4083",
  "ontology": "ontology_7d1f4a2b9c3e5081",
  "parent": "pass_5f0c8b3a6d1e4072",
  "level": "B",
  "path": "B:3e9a1c5b7d2f4083",
  "friendly_id": "PACK-24-0917",
  "ontology_version": 2,
  "publish_status": null,
  "publish_status_resolved": "draft",
  "release_number": 0,
  "values": {},
  "metadata": {},
  "created_at": "2026-07-22T14:10:43Z",
  "updated_at": "2026-07-22T14:10:43Z"
}

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

Find a passport by path

Returns the single passport at an exact path, as a full read. 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.

Optional attributes

Request

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

Response

{
  "object": "passport",
  "id": "pass_5f0c8b3a6d1e4072",
  "ontology": "ontology_7d1f4a2b9c3e5081",
  "parent": null,
  "level": "A",
  "path": "A",
  "friendly_id": null,
  "ontology_version": 1,
  "publish_status": "released",
  "publish_status_resolved": "released",
  "release_number": 1,
  "values": {
    "property_line_code": { "value": "KES-EVP-LINE-01", "language": "en", "is_fallback": false }
  },
  "metadata": {},
  "created_at": "2026-07-21T11:04:29Z",
  "updated_at": "2026-07-21T11:09:52Z",
  "discoverable_levels": ["B"],
  "discovery_chain": ["B", "C"],
  "granularity": { "tier": null, "model": null, "batch": null, "item": null }
}

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 read: values (file and image values carry short-lived download links), the resolved publish status, traversal info, and reported granularity. Requires passports:read.

Optional attributes

Request

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

Response

{
  "object": "passport",
  "id": "pass_9c4e7a1d5b3f2064",
  "ontology": "ontology_7d1f4a2b9c3e5081",
  "parent": "pass_3e9a1c5b7d2f4083",
  "level": "C",
  "path": "C:3e9a1c5b7d2f4083/9c4e7a1d5b3f2064",
  "friendly_id": "CELL-24-0917-014",
  "ontology_version": 2,
  "publish_status": "released",
  "publish_status_resolved": "released",
  "release_number": 1,
  "values": {
    "property_cell_voltage": { "value": 3.671 }
  },
  "metadata": {},
  "created_at": "2026-07-22T14:14:30Z",
  "updated_at": "2026-07-22T14:16:11Z",
  "discoverable_levels": ["B"],
  "discovery_chain": ["A", "B"],
  "granularity": { "tier": null, "model": null, "batch": null, "item": null }
}

PATCH/v1/passports/:id

Update a passport

Updates any combination of property values, friendly_id, publish_status, and metadata in one call. All values are validated against the property definitions of the passport's pinned ontology version before anything is written — a single bad value fails the whole values group with 400 value_invalid and per-property errors. Requires passports:write, plus releases:write to release a passport or take it out of release — see Releases.

The groups are applied as separate writes, in the order values → friendly_id → publish_status → metadata. Each is atomic — values is one write for the whole group — but the request isn't: a failure partway leaves the earlier groups applied. Two checks run before the first write: a status transition the release rules refuse, and the metadata limits — so a refused release or an over-limit bag leaves the values untouched. Send one group per request if partial application matters to you.

The response is the passport without the full-read fields, plus a release_run when the request started a release run. Every change emits one passport.updated event whose data.previous_attributes holds each changed field's value from before the request.

Optional attributes

  • Name
    values
    Type
    object
    Description

    A map of property id → new value. A translatable property also takes a map of language code → value, merged into its existing translations — see Translated values.

  • Name
    friendly_id
    Type
    string
    Description

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

  • Name
    publish_status
    Type
    string
    Description

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

  • Name
    include_descendants
    Type
    boolean
    Description

    With publish_status: "released" only: also release the passport's existing subtree, in a background release run. true with any other status is a 400 parameter_invalid; false is accepted on any request.

  • Name
    metadata
    Type
    object
    Description

    Merged per key into the passport's metadata.

A PATCH with an empty body changes nothing and returns the full-read shape, as GET does.

Request

PATCH
/v1/passports/pass_3e9a1c5b7d2f4083
curl -X PATCH https://api.synexcloud.com/v1/passports/pass_3e9a1c5b7d2f4083 \
  -H "Authorization: Bearer $SYNEX_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "values": { "property_capacity": 78.4, "property_serial": "KES-EVP-24-0917" },
    "friendly_id": "PACK-24-0917",
    "publish_status": "released",
    "include_descendants": true,
    "metadata": { "batch_ref": "BATCH-2026-07" }
  }'

Response

{
  "object": "passport",
  "id": "pass_3e9a1c5b7d2f4083",
  "ontology": "ontology_7d1f4a2b9c3e5081",
  "parent": "pass_5f0c8b3a6d1e4072",
  "level": "B",
  "path": "B:3e9a1c5b7d2f4083",
  "friendly_id": "PACK-24-0917",
  "ontology_version": 2,
  "publish_status": "released",
  "publish_status_resolved": "released",
  "release_number": 1,
  "values": {
    "property_capacity": { "value": 78.4 },
    "property_serial": { "value": "KES-EVP-24-0917", "language": "en", "is_fallback": false }
  },
  "metadata": { "batch_ref": "BATCH-2026-07" },
  "created_at": "2026-07-22T14:10:43Z",
  "updated_at": "2026-07-22T14:18:02Z",
  "release_run": {
    "object": "release_run",
    "id": 4822,
    "status": "pending",
    "mode": "release",
    "root": "pass_3e9a1c5b7d2f4083",
    "total_count": 0,
    "processed_count": 0,
    "skipped_count": 0,
    "failed_count": 0,
    "created_at": "2026-07-22T14:18:02Z",
    "updated_at": "2026-07-22T14:18:02Z"
  }
}

Translated values

short_text, long_text, tags, and file properties hold one value per language, in any of the 24 official EU languages: bg cs da de el en es et fi fr ga hr hu it lt lv mt nl pl pt ro sk sl sv. Every other type holds a single value. Each ontology has a default language — the one its values are authored in.

Reading a language

The endpoints that return passport values — list, find, retrieve, and update — take ?lang=<code>. Each translatable value then reads in that language, with two fields beside value:

  • Name
    language
    Type
    string
    Description

    The language value is actually in. null only when the property has no translation at all, and then value is null too.

  • Name
    is_fallback
    Type
    boolean
    Description

    true when language isn't the one you asked for.

Without ?lang, values read in the ontology's default language. When the requested language is missing, the value falls back to the default language, then to the first translation present in the code order above — and says so with is_fallback, so a missing Bulgarian text is never passed off as Bulgarian. Codes are case-insensitive and region subtags are dropped (DE and de-AT read as de); a code outside the 24 is ignored, and values read in the default language.

?lang=all reads value in the default language and adds translations: every language the property holds, keyed by code. On a full read, each translation of a file carries its own download link.

GET /v1/passports/pass_3e9a1c5b7d2f4083?lang=all

{
  "values": {
    "property_chemistry": {
      "value": "NMC-811 lithium-ion",
      "language": "en",
      "is_fallback": false,
      "translations": {
        "de": "NMC-811-Lithium-Ionen",
        "en": "NMC-811 lithium-ion"
      }
    }
  }
}

A value stored without any language — written before its property held translations — reads as a plain value, without language or is_fallback, and counts as the default language. The next write to it stores it per language.

Writing a language

  • A bare value writes the default language: "property_chemistry": "NMC-811 lithium-ion".
  • A map of language codes writes those languages: "property_chemistry": { "de": "NMC-811-Lithium-Ionen", "fr": "Lithium-ion NMC-811" }. Keys must be lowercase codes from the list — any other key (ru, DE, de-AT) fails with unsupported_language.
  • Writes merge: the languages you name are replaced, and the ones you leave out are kept.
  • An explicit null (or "", or []) for a language deletes that translation: { "fr": null }.

Text limits

Each translation is checked on its own: a short_text is at most 255 characters, a long_text 7,000, and a tags value at most 50 tags of up to 64 characters each. A translation is also capped at 14,000 bytes, which binds before the character limit only for a long_text in a script heavier than two bytes per character, such as CJK or emoji. A value over a limit fails the values group with 400 value_invalid, whose errors detail carries code value_too_long and the offending language. A value too large to store at all is 413 passport_too_large.


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.


Releases

released is the one publish status with rules of its own. draft and archived are labels; a release is a commitment — it is what the passport's public page serves, what a regulator may read, and — at the item tier's core level — what the team is billed for.

  • Explicit, never inherited. A passport is released only when its own publish_status says so. draft and archived still cascade down the chain; a passport with no explicit status under a released ancestor resolves to draft.
  • Its own ability. publish_status: "released", and any move away from released, needs releases:write on top of passports:write — 403 insufficient_permissions without it. Every other write needs passports:write alone. See Abilities.
  • Top-down. Every ancestor must be released first; otherwise the release is refused with 409 ancestor_not_released, and the message names the nearest one that isn't. An archived passport may be released directly.
  • Locked while released. A values or friendly_id write, a move to archived, and DELETE are all refused with 409 passport_released; metadata stays writable. Set it to draft (or automatic) to edit, then release again — that re-release is release_number 2.
  • Taken back bottom-up. Un-releasing a passport is refused with 409 descendants_released while anything beneath it is still released. The exception is a passport at the level that carries the ontology's item tier as its core: taking its release back cancels the billed release, drafts the passport, and drafts its released descendants in a draft-mode release run, returned as release_run like a cascade. A release already reported for billing can't be cancelled — 409 release_reported.
  • Checked first. A transition the rules refuse is checked before the values and friendly_id groups of the same request are written, so a refused release leaves the values untouched. Filling a passport in and releasing it in one call works, because the values land while it is still editable. A release that moved between the check and the write — cancelled, or released again — is 409 release_conflict; re-read and decide again.

Releasing a subtree

Send include_descendants: true with publish_status: "released" to take the passport's existing subtree with it. The passport itself is released by the time the response is written; its descendants are released by a background run, returned as release_run on the response — poll it with Retrieve a release run. On a passport that is already released, the request starts the run without re-releasing the root.

  • The cutoff. The run covers the passports that existed when the release was taken. Anything created afterwards is a new passport, released on its own terms.
  • No re-releases. A descendant that is already released, or was released once and then taken back, keeps its own release number and is counted as skipped.
  • The chain freezes. Until the run closes, releasing or un-releasing anything on its chain — the root, an ancestor, or a descendant — is refused with 409 release_in_progress.

A single release or un-release emits passport.updated. A run emits only run-level events — release_run.started, then release_run.completed or release_run.failed — never one per descendant.


DELETE/v1/passports/:id

Delete a passport

Deletes the passport and releases its friendly_id for reuse within the parent. Requires passports:write. A released passport can't be deleted (409 passport_released), and neither can any passport while a transfer is running on its ontology (409 ontology_locked; see the note on Update a passport).

Deletion is not recursive. Only the named passport is removed. Passports beneath it survive, keep their ids and friendly ids, and stay readable — but their parent points at an id that returns 404 resource_missing. Delete a branch leaf-first to remove it whole.

Request

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

Response

{
  "object": "passport",
  "id": "pass_9c4e7a1d5b3f2064",
  "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_3e9a1c5b7d2f4083/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)

The release run model

A release run is one release cascade: "release this passport and everything under it", or the same in reverse. It is opened by include_descendants on a release, or by taking back the release of an item-tier core passport — never by a request of its own. A run is bookkeeping, not a passport: it says how much of the subtree has been stamped, not what any of it now says.

  • Name
    object
    Type
    string
    Description

    Always release_run.

  • Name
    id
    Type
    integer
    Description

    Unique identifier. Release runs are integer-keyed.

  • Name
    status
    Type
    string
    Description

    pending until a worker picks the run up, running while it fans out, then complete, partial (finished, with failed_count passports it could not stamp), or failed (the run could not run at all — the root or the ontology was gone, or enumeration broke). A run that stops moving is swept and failed, so polling always ends.

  • Name
    mode
    Type
    string
    Description

    release stamps the subtree released; draft takes it back.

  • Name
    root
    Type
    string
    Description

    The passport the cascade is rooted at.

  • Name
    total_count
    Type
    integer
    Description

    Passports the run intends to touch. It accumulates as the run enumerates, so it can still be climbing while status is running — an early reading is not the final denominator.

  • Name
    processed_count
    Type
    integer
    Description

    Passports the run stamped.

  • Name
    skipped_count
    Type
    integer
    Description

    Passports the run deliberately stepped over — already released, created after the release was taken, cancelled meanwhile, or deleted. Skipping is a normal outcome and does not make a run partial.

  • Name
    failed_count
    Type
    integer
    Description

    Passports the run could not stamp. Any at all makes the finished run partial.

  • Name
    created_at
    Type
    string
    Description

    ISO 8601 timestamp of creation.

  • Name
    updated_at
    Type
    string
    Description

    ISO 8601 timestamp of the last progress update.


GET/v1/release_runs/:id

Retrieve a release run

Retrieves a release run's progress. Poll it until status is complete, partial, or failed; while it is pending or running, every release and un-release on its chain is refused with 409 release_in_progress. The id comes from the release_run on a PATCH /v1/passports/:id response.

Requires passports:read, and a key scoped to specific ontologies must cover the run's. A run belonging to another team, or an id that isn't a positive integer, is 404 resource_missing.

Request

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

Response

{
  "object": "release_run",
  "id": 4822,
  "status": "running",
  "mode": "release",
  "root": "pass_3e9a1c5b7d2f4083",
  "total_count": 1240,
  "processed_count": 875,
  "skipped_count": 12,
  "failed_count": 0,
  "created_at": "2026-07-22T14:18:02Z",
  "updated_at": "2026-07-22T14:18:44Z"
}

Was this page helpful?