Announcing v4 of the Prodigi print API
Launched in 2012, the Prodigi API has continued to evolve in line with customer feedback and expectations. As the print on demand market continues to boom, so does the need for cutting-edge technology. The latest iteration of our print fulfilment API, v4, goes live this week.
To find out more about the new version, I spoke to our API Team Lead, Tom Keepings.
So Tom, why did we need a v4?
We've had a long wishlist of changes and quality of life tweaks for a while. There were some technical reasons for the making the changes, plus some commercial ones too. Streamlining processes and making the software more intuitive were key, but we also needed to make changes to assist with launching new product ranges.
Can you tell us more about the changes — why is this a better, slicker API?
This latest version of our fulfilment API brings with it a host of new features to make our customers' lives easier.
Earlier versions of our API did not support products with multiple images gracefully. We'd have to provide customers with arbitrary, unintuitive rules to jimmy in the imagery for their products. For example, our greeting cards had to be a single image with all 4 panels stitched together, bleed included.
This jimmying was difficult, and required developer intervention to be able to convert these unusual images into a format our fulfilment lab partners needed, making each new product addition quite expensive for us and fraught with errors. We see a large part of our future lies in supporting multi-asset products: photobooks, greeting cards, diptych/triptych art panels, and more.
So we rebuilt our entire stack to support multi-asset products, and designed a new version of the API on top of that to allow anyone to order a multi-asset product in a more intuitive way. You can now simply add each image with its own named Print Area and know that it will get positioned correctly with no issues.
Quality of life improvements
With such fundamental changes under the hood, it also gaves us the opportunity to give the API a facelift. We wanted to take existing customer feedback and apply it all once while the iron was hot.
It wasn't uncommon for us to receive Customer Service queries about things that should not need a Customer Service query:
- "What attributes can I use on this product?"
- "When can I cancel my order?"
- "Why does my t-shirt need a frameColour?"
- "How much will this product cost?"
- "What shipping is available? And to where?"
- "Where can I print on a product?"
So we've simplified attribute naming, and added a couple of new really powerful endpoints.
The Quote endpoint returns a breakdown of pricing, lab allocation and shipping arrangements for a given set of items, meaning you can preview the cost and shipping for any given order before you submit it.
The Product Details endpoint queries our core product catalogue data, returning everything we know about that SKU: price, valid attributes, asset requirements, and more.
The team and I are genuinely excited to see how everyone uses these new endpoints. We know we'll be using them internally to build more tooling to help customers get costs and estimates from us (but don't tell anyone, we're still working on it!).
What was the thinking behind some of these design decisions?
It's tricky to talk design with an API. What is there to design about JSON requests and payloads? Well, quite a lot as it turns out. Some of our design principles included:
- Routes and behaviour should follow REST principals as closely as possible.
- Operations are performed against collections of resources, eg. a collection of orders.
- Endpoints that expect parameters or a payload must be explicit in their validation, returning useful error messages and status codes.
- Endpoints must be thoroughly documented.
- Only give users information they can action in a way they can help themselves.
- Only throw 500s if something has actually gone badly wrong.
- Must be self-serving and intuitive.
- Machine and human readable.
Some of these were enough on their own to guide our development, but we found it useful to expand some of the others a bit more:
This API doesn't shrug at you
It's really easy to fall into the trap of exposing the internals of a system to customers — either by throwing 500s with weird error messages that are specific to internal business logic and/or have nothing to do with the customer. Even worse, it is often something the customer can't do anything about. This is frustrating.
We worked hard to ensure that all our different API responses are caught and dealt with nicely. Didn't supply a SKU? We'll tell you that you forgot the SKU. Is it invalid? We'll tell you. Can't update that one field? We'll tell you. All with 200 and 400 status codes, saving 500s for when something actually goes badly wrong.
There's nothing worse than an API that just shrugs as a response, so we wanted to give our users the information that they can do something with. We wanted to put some control in our users hands, and let them know where and how they can help their order along.
Machine AND human readable
It's pretty easy to make an API that's machine readable, but it becomes a lot harder when it also needs to be human readable.
We know a lot of our customers don't just integrate straight into our API code/head first, and instead prefer to poke our API through tools like Postman to get a feel for what's going on. Our endpoints have been designed with this in mind, where the user might be reading the response and not a machine.
We wanted our data to be well structured, well thought out, well named, all in plain English, with deliberately chosen phrases and terminology to help make each API request as easy to understand as possible. This even comes down to the order of the fields in the response: the one-liners are at the top, and the big objects are pushed to the bottom of the response.
We've also packed a lot more information into each response, so you don't have to make 5 different requests to get all the information you want.
There are some endpoints that aren't exactly that human readable (getting a list of 100 orders is going to be a bit of a read) but the idea is that one Order on its own is.
Intuitive & self-serving
Making something intuitive feels like pushing rope uphill at times. What's intuitive for me is not always intuitive for thee.
We've done our level best to make sure that the contents of each request and response are as sensible as they can be. But we didn't just focus on the content, we focused on the requests themselves.
In v3 of the API, it would take 3 or 4 requests to create an Order. This is odd. It wouldn't be so bad if we had "basket" terminology, where you'd create one and add to it before checking out, but we don't. And we don't see many of our customers using us that way.
So instead, we've made v4 only have one request for creating an Order. After all, it's one action, so why wouldn't it be one request? We've already had great feedback on this point.
So with these changes, is now the right time to integrate with Prodigi?
It has never been a better time to integrate with Prodigi. Version 4 is our crowning achievement as a team, and we're very proud of it. Each field has been agonised over to create the best possible API to our customers.
Every single aspect of the integration with us has been simplified and improved, from authentication, to condensing our ordering process, to getting all the information you need to start selling with us.