Passports & insight

Called with brand account keys. A key only sees its own account's data. Every example uses the same sample brand, order and item, so you can follow one item from call to call.

Base URL http://62.169.23.239:8001/api/v1Auth Bearer token6 endpoints

Retrieve an item passport#

GET/brands/production-orders/{order_id}/units/{unit_id}/dpp

Requires scope dpp:read

Digital Product Passport for one unit on one of the brand's own orders.

Same material/sustainability/origin/legitimacy data as the consumer scan endpoint, but never includes ownership — the brand must not see who currently holds the item, only its on-chain status.

Parameters

  • order_idstringpathRequired

    Skannit's id for the production order. Use it in every /production-orders/{order_id} and QR call.

  • unit_idstringpathRequired

    Skannit's internal id for one item.

Returns

HTTP 200
  • unit_idstringRequired

    Skannit's internal id for one item.

  • chain_statusstring | null

    Where the item's on-chain record is: minted, activated, in_transit, at_retail, with_consumer, recalled, stolen, recycled.

  • dppobjectRequired

    Full DPP enriched from all product_ tables.

    +Show 18 child attributes
    • product_idstring | null

      Skannit's id for the product.

    • namestring | null
    • categorystring | null
    • genderstring | null
    • descriptionstring | null
    • brand_namestring | null
    • brand_logo_urlstring | null
    • gtinstring | null
    • brand_serialstring | null
    • colorstring | null

      Colour name, exactly as on the product's variants.

    • sizestring | null

      Size name, exactly as on the product's variants.

    • skustring | null

      Stock-keeping unit of the variant.

    • mediaobject
      +Show 2 child attributes
      • hero_image_urlstring | null
      • additional_imagesarray of strings
    • materialobject
      +Show 6 child attributes
      • composition_labelstring | null
      • fibersarray of objects
        +Show 2 child attributes
        • fiber_namestring | null
        • percentagenumber | null
      • elementsarray of objects
        +Show 3 child attributes
        • garment_partstring | null
        • fibersarray of objects
          +Show 2 child attributes
          • fiber_namestring | null
          • percentagenumber | null
        • gramsnumber | null

          Weight of this element at the scanned unit's size

      • total_gramsnumber | null

        Sum of element weights at the scanned unit's size

      • recycled_content_pctnumber | null
      • origin_countrystring | null
    • sustainabilityobject
      +Show 8 child attributes
      • carbon_footprint_kgnumber | null
      • water_usage_litresnumber | null
      • circularity_scoreinteger | null

        product_sustainability.circular_score, 0–100

      • is_repairableboolean | null
      • repairability_scorestring | null

        product_repairability.repair_difficulty label

      • repair_instructions_urlstring | null
      • certificationsarray of strings
      • end_of_life_instructionsstring | null
    • originobject
      +Show 3 child attributes
      • country_of_originstring | null
      • manufacturing_facilitystring | null
      • production_datestring | null
    • certificatesarray of objects

      Certificates of the production order this unit was made in.

      +Show 5 child attributes
      • cert_typestringRequired
      • certificate_numberstring | null
      • issuerstring | null
      • valid_untilstring | null
      • expiredboolean

        Defaults to false

    • dpp_sections_rawobject | null

      Raw DPP sections blob from brand_qr_batches.dpp_sections (v1 backwards compat)

  • legitimacyobjectRequired

    Result of the on-chain authenticity check.

    +Show 8 child attributes
    • verdictstringRequired
      One oflegitimatesuspiciousstolenrecalledunverified
    • notestringRequired
    • batch_registered_on_chainboolean | null
    • on_chain_batch_idinteger | null
    • merkle_rootstring | null
    • merkle_verified_on_chainboolean | null

      True when BatchRegistry.verifyItem() returned true via eth_call

    • chain_statusstring | null

      ItemNFT chain status: minted | activated | stolen | recalled | …

    • live_check_unavailableboolean

      True when the live registry check could not run and the verdict rests on the last confirmed saved record (off-chain fallback).

      Defaults to false

  • chain_linksobject

    Block-explorer references for this item's on-chain records.

    +Show 5 child attributes
    • chain_idinteger | null
    • chain_namestring | null
    • token_idinteger | null

      The item's on-chain token id.

    • token_urlstring | null

      Explorer page for this item's ownership certificate (ItemNFT token)

    • contractsobject

      Explorer links for the deployed contracts backing the passport

  • ownerobject | null

    Current holder of the OwnershipCertificate at scan time.

    +Show 5 child attributes
    • owner_typestringRequired
      One ofbrandfactoryconsumertransporterwarehouseretailrepairrecyclingexternalunknown
    • display_namestring | null
    • wallet_addressstring | null
    • is_scanning_consumerboolean

      True when the consumer scanning this item is also its on-chain owner

      Defaults to false

    • wallet_explorer_urlstring | null

      Explorer link for wallet_address; only set when the address is disclosed

GET /brands/production-orders/{order_id}/units/{unit_id}/dpp
curl
curl http://62.169.23.239:8001/api/v1/brands/production-orders/ord_8c2f4e1a9b7d3c60/units/4f282225-cbf9-531a-ae92-2567af1e350e/dpp \
  -H "Authorization: Bearer $SKANNIT_TOKEN"
200Response
json
{
  "unit_id": "4f282225-cbf9-531a-ae92-2567af1e350e",
  "chain_status": "minted",
  "dpp": {
    "product_id": "f6abe715-90aa-5908-a0a6-12951a3a21cc",
    "name": "Northwind Apparel",
    "category": "Tops",
    "gender": "unisex",
    "description": "Organic cotton tee",
    "brand_name": "Northwind Apparel",
    "brand_logo_url": "https://files.skannit.example/brand_logo.png",
    "gtin": "08712345678906",
    "brand_serial": "NW-TT-000417",
    "color": "White",
    "size": "M",
    "sku": "TT-100-WHT-M",
    "media": {
      "hero_image_url": "https://files.skannit.example/hero_image.png",
      "additional_images": [
        "additional image"
      ]
    },
    "material": {
      "composition_label": "Composition",
      "fibers": [
        {
          "fiber_name": "Fiber",
          "percentage": 72.5
        }
      ],
      "elements": [
        {
          "garment_part": "body",
          "fibers": [
            {
              "fiber_name": null,
              "percentage": null
            }
          ],
          "grams": 1
        }
      ],
      "total_grams": 24,
      "recycled_content_pct": 72.5,
      "origin_country": "PT"
    },
    "sustainability": {
      "carbon_footprint_kg": 1,
      "water_usage_litres": 1,
      "circularity_score": 1,
      "is_repairable": false,
      "repairability_score": "8/10",
      "repair_instructions_url": "https://files.skannit.example/repair_instructions.png",
      "certifications": [
        "certification"
      ],
      "end_of_life_instructions": "Return to any Northwind store for recycling"
    },
    "origin": {
      "country_of_origin": "PT",
      "manufacturing_facility": "Porto Knit",
      "production_date": "2026-11-20"
    },
    "certificates": [
      {
        "cert_type": "origin",
        "certificate_number": "GOTS-2026-11842",
        "issuer": "Control Union",
        "valid_until": "2027-10-01",
        "expired": false
      }
    ],
    "dpp_sections_raw": {}
  },
  "legitimacy": {
    "verdict": "legitimate",
    "note": "Corner of box dented",
    "batch_registered_on_chain": false,
    "on_chain_batch_id": 1,
    "merkle_root": "0x5d1e…a4c2",
    "merkle_verified_on_chain": false,
    "chain_status": "minted",
    "live_check_unavailable": false
  },
  "chain_links": {
    "chain_id": 1,
    "chain_name": "Roburna",
    "token_id": 41207,
    "token_url": "https://files.skannit.example/token.png",
    "contracts": {}
  },
  "owner": {
    "owner_type": "brand",
    "display_name": "Sam J.",
    "wallet_address": "0x7a3B5c9D1e2F4a6B8c0D2e4F6a8B0c2D4e6F8a0B",
    "is_scanning_consumer": false,
    "wallet_explorer_url": "https://files.skannit.example/wallet_explorer.png"
  }
}

Get brand analytics#

GET/brands/analytics

Requires scope analytics:read

Where this brand's goods are and what they are doing.

Complements /brands/dashboard rather than repeating it: the dashboard answers "how is the business today", this answers "what happened to the units I made" — per product, per order, per warehouse, and per scan.

Every figure is counted from real rows. Sections a brand has no data for come back empty rather than estimated.

Parameters

  • window_daysintegerquery

    How far back scan activity is counted. Stock and order figures are current state, so the window does not apply to them.

    Defaults to 90

Returns

HTTP 200
  • generated_attimestampRequired
  • window_daysinteger

    Defaults to 90

  • totalsobjectRequired
    +Show 7 child attributes
    • units_createdinteger

      Defaults to 0

    • units_soldinteger

      Defaults to 0

    • revenue_eurnumber

      Defaults to 0

    • sell_through_pctnumber

      Defaults to 0

    • productsinteger

      Defaults to 0

    • ordersinteger

      Defaults to 0

    • warehousesinteger

      Defaults to 0

  • funnelarray of objects
    +Show 4 child attributes
    • stagestringRequired
      One ofmintedin_transitat_warehouseat_retailwith_consumerrecycled
    • labelstringRequired
    • unitsinteger

      Defaults to 0

    • pct_of_totalnumber

      Share of all units the brand has ever created, so the stages sum to the whole rather than to each other.

      Defaults to 0

  • productsarray of objects
    +Show 15 child attributes
    • product_idstringRequired

      Skannit's id for the product.

    • product_namestring

      Defaults to —

    • skustring | null

      Stock-keeping unit of the variant.

    • image_urlstring | null
    • units_createdinteger

      Defaults to 0

    • units_in_transitinteger

      Defaults to 0

    • units_at_warehouseinteger

      Defaults to 0

    • units_at_retailinteger

      Defaults to 0

    • units_with_consumerinteger

      Defaults to 0

    • units_soldinteger

      Defaults to 0

    • units_removedinteger

      Defaults to 0

    • sell_through_pctnumber

      Sold ÷ created, the number a brand actually plans production against.

      Defaults to 0

    • revenue_eurnumber

      Defaults to 0

    • scansinteger

      Defaults to 0

    • claimedinteger

      Consumers who claimed ownership, i.e. the item reached a real person.

      Defaults to 0

  • ordersarray of objects
    +Show 17 child attributes
    • order_idstringRequired

      Skannit's id for the production order. Use it in every /production-orders/{order_id} and QR call.

    • production_order_idstring | null

      Human-readable order number shown in the portal (PO-YYYY-XXXX).

    • order_namestring | null
    • product_namestring

      Defaults to —

    • skustring | null

      Stock-keeping unit of the variant.

    • statusstring | null

      Current state of the object. See the allowed values.

    • tracking_statusstring | null

      Where the production order is in its lifecycle. This is the only progress field — use it, not status_display.

    • is_delayedboolean

      Defaults to false

    • priority_levelstring | null

      Order urgency.

    • factory_namestring | null
    • quantityinteger

      Number of units.

      Defaults to 0

    • units_createdinteger

      Defaults to 0

    • order_datedate | null
    • expected_deliverydate | null

      Date the goods should leave the factory.

    • days_to_deliveryinteger | null

      Negative means late. None when there is no expected date to judge against.

    • unit_cost_estimatednumber | null
    • estimated_value_eurnumber | null
  • order_summaryobjectRequired
    +Show 7 child attributes
    • total_ordersinteger

      Defaults to 0

    • delayed_ordersinteger

      Defaults to 0

    • on_time_pctnumber

      Defaults to 0

    • total_units_orderedinteger

      Defaults to 0

    • estimated_value_eurnumber

      Defaults to 0

    • by_statusobject
    • by_tracking_statusobject
  • warehousesarray of objects
    +Show 12 child attributes
    • warehouse_idstringRequired

      The warehouse account id.

    • warehouse_namestring

      Defaults to —

    • citystring | null
    • countrystring | null
    • held_boxesinteger

      Every box of this brand's the warehouse has taken in, whatever state it is now in. sealed_boxes is the subset still unopened and shippable whole.

      Defaults to 0

    • sealed_boxesinteger

      Defaults to 0

    • sealed_unitsinteger

      Defaults to 0

    • loose_unitsinteger

      Defaults to 0

    • sold_unitsinteger

      Defaults to 0

    • removed_unitsinteger

      Stock that left inventory without being sold — write-offs and recycling.

      Defaults to 0

    • expiring_sooninteger

      Defaults to 0

    • expiredinteger

      Defaults to 0

  • engagementobjectRequired
    +Show 14 child attributes
    • total_scansinteger

      Defaults to 0

    • suspicious_scansinteger

      Defaults to 0

    • unique_devicesinteger

      Distinct devices, the closest honest proxy for "people" this data allows.

      Defaults to 0

    • items_claimedinteger

      Defaults to 0

    • claim_rate_pctnumber

      Defaults to 0

    • reviewsinteger

      Defaults to 0

    • average_ratingnumber | null
    • repairsinteger

      Defaults to 0

    • recycledinteger

      Defaults to 0

    • gifts_giveninteger

      Owner-to-owner handovers of this brand's items, split by why ownership moved: a gift, a marketplace resale, or a plain private transfer (CO-08 — a gift must never silently count as a sale, or the reverse).

      Defaults to 0

    • resalesinteger

      Defaults to 0

    • private_transfersinteger

      Defaults to 0

    • dailyarray of objects
      +Show 3 child attributes
      • daydateRequired
      • scansinteger

        Defaults to 0

      • suspiciousinteger

        Defaults to 0

    • top_locationsarray of objects
      +Show 4 child attributes
      • countrystring | null
      • citystring | null
      • scansinteger

        Defaults to 0

      • suspiciousinteger

        Defaults to 0

GET /brands/analytics
curl
curl http://62.169.23.239:8001/api/v1/brands/analytics \
  -H "Authorization: Bearer $SKANNIT_TOKEN"
200Response
json
{
  "generated_at": "2026-10-09T09:30:00Z",
  "window_days": 90,
  "totals": {
    "units_created": 24,
    "units_sold": 24,
    "revenue_eur": 29,
    "sell_through_pct": 72.5,
    "products": 1,
    "orders": 1,
    "warehouses": 1
  },
  "funnel": [
    {
      "stage": "minted",
      "label": "Packed",
      "units": 24,
      "pct_of_total": 72.5
    }
  ],
  "products": [
    {
      "product_id": "f6abe715-90aa-5908-a0a6-12951a3a21cc",
      "product_name": "Trail Tee",
      "sku": "TT-100-WHT-M",
      "image_url": "https://files.skannit.example/image.png",
      "units_created": 24,
      "units_in_transit": 24,
      "units_at_warehouse": 24,
      "units_at_retail": 24,
      "units_with_consumer": 24,
      "units_sold": 24,
      "units_removed": 24,
      "sell_through_pct": 72.5,
      "revenue_eur": 29,
      "scans": 1,
      "claimed": 1
    }
  ],
  "orders": [
    {
      "order_id": "ord_8c2f4e1a9b7d3c60",
      "production_order_id": "PO-2026-7F3A",
      "order_name": "Trail Tee — AW26 drop",
      "product_name": "Trail Tee",
      "sku": "TT-100-WHT-M",
      "status": "active",
      "tracking_status": "IN-PRODUCTION",
      "is_delayed": false,
      "priority_level": "medium",
      "factory_name": "Porto Knit",
      "quantity": 1,
      "units_created": 24,
      "order_date": "2026-10-09",
      "expected_delivery": "2026-11-20",
      "days_to_delivery": 1,
      "unit_cost_estimated": 4.1,
      "estimated_value_eur": 29
    }
  ],
  "order_summary": {
    "total_orders": 24,
    "delayed_orders": 1,
    "on_time_pct": 72.5,
    "total_units_ordered": 24,
    "estimated_value_eur": 29,
    "by_status": {},
    "by_tracking_status": {}
  },
  "warehouses": [
    {
      "warehouse_id": "8bf28967-062b-532f-868c-afdf343630c2",
      "warehouse_name": "Rotterdam DC",
      "city": "Rotterdam",
      "country": "NL",
      "held_boxes": 24,
      "sealed_boxes": 24,
      "sealed_units": 24,
      "loose_units": 24,
      "sold_units": 24,
      "removed_units": 24,
      "expiring_soon": 1,
      "expired": 1
    }
  ],
  "engagement": {
    "total_scans": 24,
    "suspicious_scans": 1,
    "unique_devices": 1,
    "items_claimed": 1,
    "claim_rate_pct": 72.5,
    "reviews": 1,
    "average_rating": 1,
    "repairs": 1,
    "recycled": 1,
    "gifts_given": 1,
    "resales": 1,
    "private_transfers": 1,
    "daily": [
      {
        "day": "2026-11-20",
        "scans": 1,
        "suspicious": 1
      }
    ],
    "top_locations": [
      {
        "country": "NL",
        "city": "Rotterdam",
        "scans": 1,
        "suspicious": 1
      }
    ]
  }
}

List resales#

GET/brands/repair/secondary-market

Requires scope analytics:read

Secondary Market Insights: KPI cards and resale listing table.

Parameters

  • pageintegerquery

    Defaults to 1

  • limitintegerquery

    Defaults to 5

Returns

HTTP 200
  • kpi_cardsarray of objectsRequired
    +Show 5 child attributes
    • labelstringRequired
    • valuestringRequired
    • deltastring | null
    • delta_directionstring | null
      One ofupdown
    • progress_pctnumber | null
  • itemsarray of objectsRequired

    The objects on this page.

    +Show 7 child attributes
    • listing_idstringRequired
    • product_skustringRequired
    • original_pricestringRequired
    • resale_pricestringRequired
    • conditionstringRequired
      One ofNewPristineGoodFairPoor
    • authentication_statusstringRequired
      One ofVerifiedPendingRejected
    • date_solddate | null
  • paginationobjectRequired

    Page position: current_page, limit, total_pages, total_results.

    +Show 6 child attributes
    • total_resultsintegerRequired
    • total_pagesintegerRequired
    • current_pageintegerRequired
    • limitintegerRequired
    • showing_fromintegerRequired
    • showing_tointegerRequired
GET /brands/repair/secondary-market
curl
curl http://62.169.23.239:8001/api/v1/brands/repair/secondary-market \
  -H "Authorization: Bearer $SKANNIT_TOKEN"
200Response
json
{
  "kpi_cards": [
    {
      "label": "Packed",
      "value": "1,284",
      "delta": "+12%",
      "delta_direction": "up",
      "progress_pct": 72.5
    }
  ],
  "items": [
    {
      "listing_id": "6479a0b9-8a75-5095-897a-15823ecb26d8",
      "product_sku": "TT-100-WHT-M",
      "original_price": "€29.00",
      "resale_price": "€21.00",
      "condition": "New",
      "authentication_status": "Verified",
      "date_sold": "2026-11-20"
    }
  ],
  "pagination": {
    "total_results": 24,
    "total_pages": 24,
    "current_page": 1,
    "limit": 1,
    "showing_from": 1,
    "showing_to": 1
  }
}

Get resale trends#

GET/brands/repair/secondary-market/analytics

Requires scope analytics:read

Resale trend chart (last 30 days) and top resale categories.

Returns

HTTP 200
  • resale_trendsarray of objectsRequired
    +Show 3 child attributes
    • date_labelstringRequired
    • market_pricestring | null
    • volumeinteger | null
  • top_resale_categoriesarray of objectsRequired
    +Show 2 child attributes
    • categorystringRequired
    • percentnumber

      Defaults to 0

GET /brands/repair/secondary-market/analytics
curl
curl http://62.169.23.239:8001/api/v1/brands/repair/secondary-market/analytics \
  -H "Authorization: Bearer $SKANNIT_TOKEN"
200Response
json
{
  "resale_trends": [
    {
      "date_label": "2026-11-20",
      "market_price": "€24.00",
      "volume": 1
    }
  ],
  "top_resale_categories": [
    {
      "category": "Tops",
      "percent": 72.5
    }
  ]
}

List recycled items#

GET/brands/repair/recycled

Requires scope analytics:read

Recycled Items Ledger with KPI cards and state filter.

Parameters

  • pageintegerquery

    Defaults to 1

  • limitintegerquery

    Defaults to 5

  • statestringquery

    REPURPOSED | SORTED | SHREDDED | RESALE READY | PENDING

Returns

HTTP 200
  • kpi_cardsarray of objectsRequired
    +Show 6 child attributes
    • labelstringRequired
    • valuestringRequired
    • deltastring | null
    • delta_directionstring | null
      One ofupdown
    • sub_labelstring | null
    • status_tagstring | null
  • itemsarray of objectsRequired

    The objects on this page.

    +Show 14 child attributes
    • item_idstringRequired
    • product_categorystring | null
    • processing_facilitystringRequired
    • current_statestringRequired
      One ofREPURPOSEDSORTEDSHREDDEDRESALE READYPENDING
    • circularity_scorestringRequired
      One ofHighMediumLow
    • processed_attimestampRequired
    • sourcestring

      Defaults to brand

    • consumer_recycle_request_idinteger | null
    • notesstring | null
    • product_namestring | null
    • product_idstring | null

      Skannit's id for the product.

    • gtinstring | null
    • serial_numberstring | null
    • consumer_namestring | null
  • paginationobjectRequired

    Page position: current_page, limit, total_pages, total_results.

    +Show 6 child attributes
    • total_resultsintegerRequired
    • total_pagesintegerRequired
    • current_pageintegerRequired
    • limitintegerRequired
    • showing_fromintegerRequired
    • showing_tointegerRequired
GET /brands/repair/recycled
curl
curl http://62.169.23.239:8001/api/v1/brands/repair/recycled \
  -H "Authorization: Bearer $SKANNIT_TOKEN"
200Response
json
{
  "kpi_cards": [
    {
      "label": "Packed",
      "value": "1,284",
      "delta": "+12%",
      "delta_direction": "up",
      "sub_label": "last 30 days",
      "status_tag": "on track"
    }
  ],
  "items": [
    {
      "item_id": "Qm7xK2pL9vR4tY8wZ1nB3c",
      "product_category": "Tops",
      "processing_facility": "ReLoop Recycling",
      "current_state": "REPURPOSED",
      "circularity_score": "High",
      "processed_at": "2026-10-09T09:30:00Z",
      "source": "web_shop",
      "consumer_recycle_request_id": 1,
      "notes": "Received at dock 3",
      "product_name": "Trail Tee",
      "product_id": "f6abe715-90aa-5908-a0a6-12951a3a21cc",
      "gtin": "08712345678906",
      "serial_number": "000417",
      "consumer_name": "Consumer"
    }
  ],
  "pagination": {
    "total_results": 24,
    "total_pages": 24,
    "current_page": 1,
    "limit": 1,
    "showing_from": 1,
    "showing_to": 1
  }
}

Get recycling trends#

GET/brands/repair/recycled/analytics

Requires scope analytics:read

Processing trends (last 7 days) and real-time processing logs.

Returns

HTTP 200
  • processing_trendsarray of objectsRequired
    +Show 2 child attributes
    • daystringRequired
    • unitsintegerRequired
  • processing_logsarray of objectsRequired
    +Show 4 child attributes
    • log_idstringRequired
    • messagestringRequired
    • log_typestringRequired
      One ofcompletedscanpassanomaly
    • occurred_atstringRequired
GET /brands/repair/recycled/analytics
curl
curl http://62.169.23.239:8001/api/v1/brands/repair/recycled/analytics \
  -H "Authorization: Bearer $SKANNIT_TOKEN"
200Response
json
{
  "processing_trends": [
    {
      "day": "2026-11-20",
      "units": 24
    }
  ],
  "processing_logs": [
    {
      "log_id": "184a594f-77ac-5c65-988c-4f2a58896a83",
      "message": "Print job sent to Porto Labels",
      "log_type": "completed",
      "occurred_at": "2026-10-09T09:30:00Z"
    }
  ]
}