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.
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.
| Consumer | Arrives how | Wants |
|---|---|---|
| Consumer with a phone | Camera scan | A rendered page, in their language |
| Recycler | Scanner or system | Structured data, treatment fields |
| Regulator | Browser or API | Full record, with provenance |
| Retail partner | Server integration | Structured data, commercial fields |
| Search engine or model | Crawl | Structured, crawlable public data |
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.
- AnonymousPublic attributes only; no identification needed.
- Pre-registered partnerAPI credentials; works where a relationship exists.
- Credential holderPresents a verifiable credential proving a role.
- AuthorityRecognised through a credential or a register.
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
- GS1 Digital Link standard — GS1, 2024-01
- Regulation (EU) 2024/1781 establishing a framework for ecodesign requirements — EUR-Lex, European Union, 2024-06