CirculeID

concept

Designing a DPP API

A passport API serves scanners, regulators, recyclers and partners at once. The decisions that outlive the first version, and the ones that quietly do not.

CirculeID Research6 min read1,294 words

A passport API has to serve anonymous consumer scans, authenticated partner integrations and regulator access from one identifier. The decisions that matter most are content negotiation, how audience scope is enforced, and how a historical version of a record is requested.

What this gives you

The four resources a passport API needs, the error and pagination contract that keeps integrations stable, and the design choices that are expensive to change later.

Key takeaways

  • Content negotiation on the identifier is what makes one link serve every consumer.
  • Audience scope must be enforced in the data layer, never in a response formatter.
  • Time-qualified reads are a compliance requirement, not a convenience feature.
  • Rate limiting an anonymous public endpoint is harder than it first appears.

A passport API is unusual among enterprise APIs in that most of its traffic comes from parties you have no relationship with, arriving through a physical product rather than through an integration project.

That shapes almost every design decision, and several conventions that work well for partner APIs are actively wrong here.

One identifier, many consumers

The identifier printed on a product is fixed for the life of that product. Everything that varies — the audience, the format, the language, the depth of data — has to be resolved at request time.

Who arrives at a passport identifier, and what each one needs back
ConsumerArrives howWants
Consumer with a phoneCamera scanA rendered page, in their language
RecyclerScanner or systemStructured data, treatment fields
RegulatorBrowser or APIFull record, with provenance
Retail partnerServer integrationStructured data, commercial fields
Search engine or modelCrawlStructured, crawlable public data
Who arrives at a passport identifier, and what each one needs back

Content negotiation is what makes one link serve all of them. A request with an HTML accept header gets a page; the same URI with a JSON accept header gets structured data. GS1 Digital Link is built around exactly this behaviour, which is a good reason to follow it rather than invent a parallel scheme.

Audience scope belongs in the data layer

The public and permissioned split is the part most likely to be implemented in the wrong place, and the failure is not visible until an integration exposes it.

The reliable arrangement is that scope is a property of each attribute, evaluated when the record is assembled against the caller’s established identity. Every response path then inherits the same rule, including ones written later by people who never read the original design.

Time-qualified reads

A market surveillance question concerns what a passport asserted when a product was placed on the market, which may be years before the question is asked.

The API therefore needs a way to request a record as at a date, returning what would have been served then. This is not an audit log — an audit log records that a change occurred, while this returns the actual state.

Building it later is substantially harder than building it first, because retrofitting requires reconstructing history from change records that were never designed to support reconstruction.

Identity of the caller

Permissioned access needs the caller to be identified, and the mechanism has to work for parties who were not anticipated when the system was built.

Pre-registration does not scale to parties you never met.

The third option is the one that makes the model work at scale. A recycler in another member state cannot realistically pre-register with every manufacturer whose products they handle, and a credential proving they hold a waste treatment authorisation solves that without a bilateral relationship.

The anonymous traffic problem

A public endpoint reachable by scanning a product cannot require authentication, which makes ordinary abuse controls awkward.

  • Rate limiting by address misfires when a shop’s customers share one network connection.
  • Blocking automated access conflicts with wanting search engines and AI crawlers to index public data.
  • Caching aggressively helps, and interacts badly with attributes that change in service.
  • Scan telemetry is useful for duplicate detection and is personal data handling requiring a lawful basis.

The second point is worth stating clearly because teams frequently apply bot protection reflexively. Public passport data is meant to be crawled, and blocking crawlers defeats a substantial part of why the data is public.

Versioning the API, not just the data

Two kinds of versioning are in play and conflating them causes confusion later. The record has versions over time; the API contract also changes as requirements evolve.

Attribute definitions will be added as delegated acts arrive under Regulation (EU) 2024/1781. An API that treats attributes as data against declared definitions absorbs that; one that hard-codes fields into its response schema requires a breaking change each time.

Since the identifier on a product cannot change, the URI must remain stable across every API version. Versioning belongs in negotiation or in a header, never in the path that a product is physically marked with.

This constraint is easy to accept in principle and easy to violate in practice, because putting a version in the path is the most common convention in general API design. A team applying their house style without thinking about the physical marking will produce identifiers that expire.

The consequence is not recoverable by a redirect either, at least not indefinitely. Products marked with a versioned path create an obligation to keep that path resolving for as long as any of those products exist, which for durable goods means decades of maintaining a route nobody wanted.

Frequently asked questions

How does one link serve consumers and machines?

Through content negotiation. A request with an HTML accept header returns a rendered page while the same URI with a JSON accept header returns structured data. GS1 Digital Link is built around exactly this behaviour, which is a good reason to follow it rather than invent something parallel.

Where should audience scope be enforced?

In the data layer, as a property of each attribute evaluated when the record is assembled. Implementing it in a page renderer produces the classic failure where a JSON endpoint added later returns the full record, exposing commercially sensitive supplier data to anybody who asks.

What is a time-qualified read?

A request for the record as it stood at a given date, returning what would have been served then. Market surveillance questions concern what a passport asserted when a product was placed on the market, which may be years before anybody asks about it.

Can we add historical reads later?

It is substantially harder than building them in from the start. Retrofitting means reconstructing history from change records that were never designed to support reconstruction, and for the earliest data that is frequently impossible, because the previous values were simply overwritten in place.

How do unknown parties get permissioned access?

Through verifiable credentials rather than pre-registration. A recycler in another member state cannot realistically pre-register with every manufacturer whose products they handle, and a credential proving they hold a waste treatment authorisation solves that without any bilateral relationship existing first.

Should we block bots on the public endpoint?

No, and teams apply bot protection reflexively here. Public passport data is meant to be crawled by search engines and AI systems, and blocking crawlers defeats a substantial part of the reason the data is public in the first place.

Where does API version go in the URI?

Nowhere. The identifier is physically marked on the product and cannot change, so the URI must stay stable across every API version. Versioning belongs in content negotiation or a header, never in a path that has already been printed onto physical goods.

Sources

  1. GS1 Digital Link standardGS1, 2024-01
  2. Regulation (EU) 2024/1781 establishing a framework for ecodesign requirementsEUR-Lex, European Union, 2024-06

Continue reading

Next step

これを基に作られたパスポートを見る

CirculeIDは、上で述べた要件を、貴社製品向けに実際に機能するデジタル製品パスポートへと変えます。

Index