# Ordering PCBs directly from within the application

**URL:** <https://librepcb.discourse.group/t/ordering-pcbs-directly-from-within-the-application/360>\
**Category:** Improvement Ideas\
**Created:** [January 16, 2021, 11:34pm UTC](https://librepcb.discourse.group/t/ordering-pcbs-directly-from-within-the-application/360 "2021-01-16T23:34:19Z")\
**Posts on this page:** 11\
**Page:** 1

<div class="post-metadata">

**Author:** ![ubruhin](https://avatars.discourse-cdn.com/v4/letter/u/c89c15/32.png) [@ubruhin](https://librepcb.discourse.group/u/ubruhin)\
**Post date:** [January 16, 2021, 11:34pm UTC](https://librepcb.discourse.group/t/ordering-pcbs-directly-from-within-the-application/360/1 "2021-01-16T23:34:19Z")

</div>

# Idea

Currently the user has to generate Gerber files manually and then needs to upload them to a PCB manufacturer service website. This is fine for many users, especially for those who are familiar with the Gerber format and the ordering process in general. But I think there are many hobbyists creating their first PCBs, who do not really know what steps are needed to order a PCB. I remember myself struggling with the whole order process when I created my first PCBs with Eagle a long time before studying electronics - it helped me a lot that PCB manufacturers natively supported Eagle project files 😉

Thanks to the cooperation with Aisler, there is already a simpler way to order PCBs (export \*.lppz and upload it to Aisler). However, most people probably don’t know Aisler yet. And although it’s simpler than exporting Gerber, it still involves some kind of file export and manually needs to be uploaded to a website. Therefore I think it would be quite helpful to somehow integrate the ordering process directly into LibrePCB. This would have several advantages:

- Especially for beginners, it’s way easier to get the PCB ordered. No knowledge is needed about the Gerber format or about what PCB manufacturers exist and which file formats they accept.
- Not only beginners, even engineers with knowledge about the order process might sometimes choose a simple order method if it reduces effort/time and the project is not very critical regarding reproducibility, price etc. (e.g. prototypes).
- With a cooperation between the used PCB manufacturer and LibrePCB, we might be able to increase our income with every PCB ordered through LibrePCB. This supports the development of LibrePCB, which in turn helps LibrePCB users since LibrePCB gets more and more powerful. Currently only a few people order PCBs at Aisler, so it doesn’t generate significant income for LibrePCB. The ability to order PCBs directly from within LibrePCB might lead to many more users ordering at a manufacturer which supports LibrePCB financially.

# Possible Risks

## Community doesn’t like it

Maybe users could consider such a feature as too commercial for an OpenSource project (e.g. “advertising” for Aisler) 😉 My opinion: As explained above, creating more income is good for LibrePCB and its users since it helps to keep the LibrePCB development alive. And users who don’t like this feature, don’t need to use it (of course we will always provide the ability to export Gerber files as usual, which you can send to whatever PCB manufacturer you like).

## Breaking changes in manufacturers API

If some day the cooperation between PCB manufacturers and LibrePCB changes (added more cooperations, stopped a cooperation, breaking change in manufacturer API, …), this feature might stop working in all existing LibrePCB releases.

IMHO this would be a nightmare and thus needs to be avoided. This means that the application itself should **not** contain any hardcoded information about the supported manufacturers and their API to order PCBs.

# Implementation proposal

I’d suggest to implement such a feature in a very simple way:

- In the board editor, add a menu item _File -\> Order PCBs_ (or something like that).
- This menu item opens a window which contains some explanation how this feature works etc (e.g. privacy statement, since the project gets forwarded to a manufacturer), and a button like “Upload project & start order process”.
- The button uploads the project as a \*.lppz through [our own HTTPS API](https://developers.librepcb.org/d1/dcb/doc_server_api.html) to our server (\*).
- The API responds with an URL.
- LibrePCB opens that URL in the system’s default browser. The URL will point to a page to start the ordering process (e.g. might point directly to the PCB manufacturer website, but with the Gerber data already loaded).

(\*) _Actually the user can specify an arbitrary list of API servers in the workspace settings. The PCB ordering feature should check all available APIs whether they support this feature or not. If multiple APIs support the feature, the user should be able to choose through which API he wants to order the PCB._

This way we are very flexible regarding PCB manufacturer integration. Only the API server needs to be kept up to date with the supported manufacturers. If a manufacturer changes its own API, the LibrePCB application will continue to work since the fix needs to be done server side.

In addition, the feature is independent of what file format the PCB manufacturer expects. Since the whole project gets uploaded as a \*.lppz, the server can convert it to any other format needed by the manufacturer (e.g. Aisler supports \*.lppz natively so no conversion is needed, but other manufacturers might need Gerber files which could then be generated on our server).

In the end, this seems to be very similar to [Fritzing Fab](https://fritzing.org/services/fab) 🙂

# Feedback

Any thoughts about such a feature? Does it sound like a good or bad idea? Any improvement suggestion? 🙂

---

<div class="post-metadata">

**Author:** ![hooperbloob](https://yyz2.discourse-cdn.com/free1/user_avatar/librepcb.discourse.group/hooperbloob/32/48_2.png) [@hooperbloob](https://librepcb.discourse.group/u/hooperbloob)\
**Post date:** [January 18, 2021, 6:33pm UTC](https://librepcb.discourse.group/t/ordering-pcbs-directly-from-within-the-application/360/2 "2021-01-18T18:33:25Z")

</div>

Sounds like a great idea. In fact it could provide a table listing all the manufacturers able to produce the board. Sortable columns shown would include name, website url, prices for 1, 2, 5, 10 units etc, estimated delivery time, checkboxes for available options (silk screen, etc), and user comments. Some manufacturers could be shown across multiple rows if they provide various material types, thicknesses, etc.

---

<div class="post-metadata">

**Author:** ![EdizonTN](https://yyz2.discourse-cdn.com/free1/user_avatar/librepcb.discourse.group/edizontn/32/222_2.png) [@EdizonTN](https://librepcb.discourse.group/u/EdizonTN)\
**Post date:** [January 27, 2021, 3:07pm UTC](https://librepcb.discourse.group/t/ordering-pcbs-directly-from-within-the-application/360/3 "2021-01-27T15:07:17Z")

</div>

Hmm,  
I try to thinking little more about this.

For beginners/DYI can be this feature as easiest way how to order PCB. But beginners/DYI needs low cost manufacturers.  
And this is question - price value for LibrePCB from ordered low cost PCBs via push button. **Will be this value sufficient in opposite to time/price needed to program and test this feature?**

From my point of view (as not the beginner designer) is this feature not useable, but doesn’t mind. I 'll accept it, but probably I will not used it.  
Because my last check of the design is check manufacturer (gerber) data.  
How I check mfg data if I order it via this button? No way, maybe.

---

<div class="post-metadata">

**Author:** ![ubruhin](https://avatars.discourse-cdn.com/v4/letter/u/c89c15/32.png) [@ubruhin](https://librepcb.discourse.group/u/ubruhin)\
**Post date:** [January 31, 2021, 6:44pm UTC](https://librepcb.discourse.group/t/ordering-pcbs-directly-from-within-the-application/360/4 "2021-01-31T18:44:25Z")

</div>

Thanks for the feedback @hooperbloob and @EdizonTN! 🎉

> [@hooperbloob](#):
>
> In fact it could provide a table listing all the manufacturers able to produce the board. Sortable columns shown would include name, website url, prices for 1, 2, 5, 10 units etc, estimated delivery time, checkboxes for available options (silk screen, etc), and user comments.

At this time I don’t know if this will ever be possible (e.g. knowing the price is almost impossible if manufacturers don’t provide an API for this and it is not documented how to calculate it). Anyway, for now I think it’s sufficient to support only a single manufacturer, but I agree it might make sense to add more manufacturers in future.

> [@EdizonTN](#):
>
> And this is question - price value for LibrePCB from ordered low cost PCBs via push button. **Will be this value sufficient in opposite to time/price needed to program and test this feature?**

Very hard to say 😉 But I’d say if such a feature makes ordering PCBs much easier, it might attract new users. And more users is always good, even if it doesn’t lead to more income.

> [@EdizonTN](#):
>
> Because my last check of the design is check manufacturer (gerber) data.  
> How I check mfg data if I order it via this button? No way, maybe.

Actually on Aisler you’ll see the rendered PCB before ordering it, and (in contrast to most/all other manufacturers) they guarantee that the preview is identical to the real PCB. But of course I understand that one wants to do the review in a Gerber viewer instead 🙂

I worked on a prototype for this feature, so far it seems to work. This is how it looks at the moment:

![librepcb-order](https://global.discourse-cdn.com/free1/uploads/librepcb1/original/1X/bf516f7998e7236840bef36045fe64f84bab6560.gif)

---

<div class="post-metadata">

**Author:** ![EdizonTN](https://yyz2.discourse-cdn.com/free1/user_avatar/librepcb.discourse.group/edizontn/32/222_2.png) [@EdizonTN](https://librepcb.discourse.group/u/EdizonTN)\
**Post date:** [January 31, 2021, 7:07pm UTC](https://librepcb.discourse.group/t/ordering-pcbs-directly-from-within-the-application/360/5 "2021-01-31T19:07:44Z")

</div>

Ouu, Preview of the PCB looks good! This can be the sufficient.

> Very hard to say 😉 But I’d say if such a feature makes ordering PCBs much easier, it might attract new users. And more users is always good, even if it doesn’t lead to more income.

But don’t forget, more functionality + easy of use = more users.  
In LibrePCB case will be more users if will be finished (and easy useable) basic functions (easiest layer change in PCB, moving Value and Name in schematic etc…) - I still waiting for these. This is a my point of view.

At the end - if you make ANY decision, I will still propagate LibrePCB. Because I feel it his potential. 👍

---

<div class="post-metadata">

**Author:** ![hooperbloob](https://yyz2.discourse-cdn.com/free1/user_avatar/librepcb.discourse.group/hooperbloob/32/48_2.png) [@hooperbloob](https://librepcb.discourse.group/u/hooperbloob)\
**Post date:** [January 31, 2021, 7:53pm UTC](https://librepcb.discourse.group/t/ordering-pcbs-directly-from-within-the-application/360/6 "2021-01-31T19:53:27Z")

</div>

> [@ubruhin](#):
>
> At this time I don’t know if this will ever be possible (e.g. knowing the price is almost impossible if manufacturers don’t provide an API for this and it is not documented how to calculate it). Anyway, for

When Google let public transportation providers include their services on Google Maps they didn’t ask each of them to provide APIs for their bus schedules and locations. They published their own interface in the form of a structured doc (JSON?) that those providers could provide for inclusion in the maps. I think they do the same thing for businesses, noting their hours of operation, website url, etc.

So, to follow that example, you could mock up a sample specification doc for your favourite PCB provider and, after a few iterations, use that going forward for other manufacturers. If someone wants to be considered for inclusion as a service provider in LibrePCB, they can send you a URL of where that spec doc lives on _their_ website so LibrePCB can pull the latest version every time. You would only be responsible for maintaining (vetting?) the list of service providers and those URLs so when the application starts it can download the list (from librepcb,org) and then pull the latest docs from each of the providers.

This way you don’t have to compare apples to oranges in terms of available options, the onus is now on the providers to do that. You just allow for them in your master specification.

---

<div class="post-metadata">

**Author:** ![ubruhin](https://avatars.discourse-cdn.com/v4/letter/u/c89c15/32.png) [@ubruhin](https://librepcb.discourse.group/u/ubruhin)\
**Post date:** [September 30, 2021, 9:35am UTC](https://librepcb.discourse.group/t/ordering-pcbs-directly-from-within-the-application/360/7 "2021-09-30T09:35:23Z")

</div>

There’s some progress regarding this feature! 😃

# Server Side

I called the server side implementation of this feature “LibrePCB Fab” and hosted it at [https://fab.librepcb.org/](https://fab.librepcb.org/). Of course it’s very rudimentary at the moment, but this could be improved step by step.

# Client Side

My proposal how this feature is included into the application:

 ![image](https://global.discourse-cdn.com/free1/uploads/librepcb1/original/1X/7b6d57dfceaa66794c71c6189ef9521ec7af5cb8.png)

I called it a “preview feature” because the feature relies on the availability of several webservices. We have no experience yet how reliable the whole feature works, so IMHO it’s good to let users know that there _might_ still be some issues.

# API Landing Page

As a potential user of such a feature, I’d like to know what will happen with my project (e.g. privacy policy) _before_ uploading it. So the dialog provides an URL where this information is stated. My idea is to include this [Landing Page](https://developers.librepcb.org/_branches/order-pcb-via-api/d1/dcb/doc_server_api.html#doc_server_api_landingpage) specification into our API documentation.

I also set up that page already: [https://api.librepcb.org/api/](https://api.librepcb.org/api/)

I’m not 100% happy with it since basically it just points to [fab.librepcb.org/about](https://fab.librepcb.org/about) so you have to follow the link to finally find the privacy policy. The reason why I did it that way is that the API server and LibrePCB Fab are completely different services.

Note that I don’t like to hardcode [fab.librepcb.org/about](https://fab.librepcb.org/about) directly into the application. The application uses the API server which is configured in the workspace settings, so if one uses another API server, [fab.librepcb.org/about](https://fab.librepcb.org/about) would be the wrong URL.

# API Specification

I have written specifications of the API which the application will use to start the order process via API server. But I had two different ideas and could not yet decide which one is better 🙈

- Variant 1 - only a single POST request with response: ![image](https://global.discourse-cdn.com/free1/uploads/librepcb1/original/1X/b8bd18ebeedb4a04d766d9168370c7e9f26c8b7a.png)
- Variant 2 - a GET request with response, then a POST request with response: ![image](https://global.discourse-cdn.com/free1/uploads/librepcb1/original/1X/8811b4b993a5746bc925548af7a40e3254450fc7.png)

I like variant 1 because of its simplicity. Variant 2 is a bit more complicated, but has some advantages:

- Ability to reject an upload _before_ the client starts the (large, time/memory consuming) POST request. Examples: Service temporarily not available, file size too large, some kind of rate limit, …
- Easier to keep the API server completely decoupled from the upload server. With variant 1 this would need to be done by webserver configuration to forward the `/api` POST request to another server. With variant 2, this can even be done with a simple, static JSON file which contains the URL of the upload server (so the API server can be a dumb static file server).
- More flexibility in general. For example, the maximum allowed filesize can be defined on server side instead of hardcoding it into the application (although this might also be possible by rejecting the POST request dependent on the `Content-Length` header?).

Due to these advantages, currently I tend to go with variant 2.

# Feedback

Any feedback about each part of this feature (dialog GUI, API spec, landing page, …) is very welcome 🙂

@dbrgn I suspect you have much more experience with web technologies and APIs, maybe you could take a look at this? 😉

---

<div class="post-metadata">

**Author:** ![Doom](https://avatars.discourse-cdn.com/v4/letter/d/a587f6/32.png) [@Doom](https://librepcb.discourse.group/u/Doom)\
**Post date:** [October 17, 2021, 8:28am UTC](https://librepcb.discourse.group/t/ordering-pcbs-directly-from-within-the-application/360/8 "2021-10-17T08:28:26Z")

</div>

I just want to share a link for PCB price comparison : [https://pcbshopper.com/](https://pcbshopper.com/)

And to get incomes to help the project, I think buying components through LibrePCB would be great and really helpful.  
But I don’t know if it is possible to get an agreement to get 1 or 2% with Mouser or Digikey.

Designspark use this kind of method to earn money (even if it is a little bit different as it is from RS).

---

<div class="post-metadata">

**Author:** ![ubruhin](https://avatars.discourse-cdn.com/v4/letter/u/c89c15/32.png) [@ubruhin](https://librepcb.discourse.group/u/ubruhin)\
**Post date:** [October 17, 2021, 11:41am UTC](https://librepcb.discourse.group/t/ordering-pcbs-directly-from-within-the-application/360/9 "2021-10-17T11:41:06Z")

</div>

The feature is now ready, pull request opened!

> <https://github.com/LibrePCB/LibrePCB/pull/927>
>
> \## Feature description
> 
> This PR adds a new feature to the schematic- and board… editors; a dialog which allows to directly start ordering the PCB. For details, refer to the discussion about this feature in our forum: https://librepcb.discourse.group/t/ordering-pcbs-directly-from-within-the-application/360
> 
> The feature is intended mainly for users not familiar with the normal ordering process (Gerber/Excellon export, configuring correct export settings, uploading to manufacturers website, ...). But to be honest, I think it is even useful for power users (at least hobbyists), since it is way simpler and faster to order a PCB this way :wink: However, this way you can't choose the manufacturer on your own, at least not yet (the web service can be improved at any time later).
> 
> Beside the practical part of this feature, we hope it also helps to keep the development of LibrePCB ongoing because for each order done through this service, AISLER (the company which will process our orders) will make a donation to the LibrePCB project :heart: 
> 
> \## How it works
> 
> Our server API has been extended with an endpoint for this service. See details \[here\](https://developers.librepcb.org/\_branches/order-pcb-via-api/d1/dcb/doc\_server\_api.html#doc\_server\_api\_resources\_order).
> 
> A new dialog in the schematic- and board editor accesses this API to upload the project as an \*.lppz archive to the API server. Afterwards, the order process needs to be continued in the web browser. This web service is hosted at https://fab.librepcb.org/ (it is also usable by manually uploading the \*.lppz). See details at https://fab.librepcb.org/about.
> 
> \## Screenshots
> 
> The board-and schematic editors contain a new icon in the toolbar, which opens the following dialog.
> 
> \### Before starting the upload
> 
> !\[image\](https://user-images.githubusercontent.com/5374821/137624607-0c28cb8c-3f09-4b15-98ca-6274d18b2ccc.png)
> 
> \### After the upload
> 
> !\[image\](https://user-images.githubusercontent.com/5374821/137624842-e12d93c1-476a-4e57-9d42-33cb83d6b726.png)
> 
> \### The whole workflow
> 
> !\[librepcb-order-pcb-2\](https://user-images.githubusercontent.com/5374821/137625133-d52c8293-0927-44d6-a508-3f565d3301a8.gif)

I decided to go with variant 2, i.e. two separate API requests. In addition, I removed the need for a landing page - the response of the first API request now contains the direct link to [fab.librepcb.org/about](https://fab.librepcb.org/about) (JSON key `info_url`), which can be shown in the LibrePCB UI without hardcoding it into the source code. It just requires to execute the first GET request immediately when opening the dialog, but actually now I even like this way because now we can show error messages (service not available, no internet connection, …) immediately, not just when the user clicks on the upload button (much faster feedback - the upload button only appears if the API is accessible).

So I think I’ll delete the landing page [api.librepcb.org/api](https://api.librepcb.org/api/) soon since it is not needed anymore.

How the API looks now:

![image](https://global.discourse-cdn.com/free1/uploads/librepcb1/original/1X/6dde9cc3d05f812ba282dd74b4de15cba02bbf52.png)

* * *

> [@Doom](#):
>
> And to get incomes to help the project, I think buying components through LibrePCB would be great and really helpful.  
> But I don’t know if it is possible to get an agreement to get 1 or 2% with Mouser or Digikey.

Absolutely, I also have this idea in my mind for quite some time 😃 I think the way how the “Order PCB” feature is now implemented, we have the flexibility to extend the web service step by step. So we could add the ability to buy components directly in the webinterface, no need to adjust LibrePCB anymore. Since the whole project is uploaded as a \*.lppz, the web service could also export and process the BOM in addition to the Gerber files.

However, these are kind of long term ideas, with low priority…

---

<div class="post-metadata">

**Author:** ![dbrgn](https://yyz2.discourse-cdn.com/free1/user_avatar/librepcb.discourse.group/dbrgn/32/25_2.png) [@dbrgn](https://librepcb.discourse.group/u/dbrgn)\
**Post date:** [October 25, 2021, 1:33pm UTC](https://librepcb.discourse.group/t/ordering-pcbs-directly-from-within-the-application/360/10 "2021-10-25T13:33:09Z")

</div>

I think this looks great for a first version. I agree that the two-step upload makes sense. 👍

---

<div class="post-metadata">

**Author:** ![ubruhin](https://avatars.discourse-cdn.com/v4/letter/u/c89c15/32.png) [@ubruhin](https://librepcb.discourse.group/u/ubruhin)\
**Post date:** [October 28, 2021, 6:11pm UTC](https://librepcb.discourse.group/t/ordering-pcbs-directly-from-within-the-application/360/11 "2021-10-28T18:11:26Z")

</div>

Feature implemented! Will be part of LibrePCB 0.1.6 🎉

> <https://github.com/LibrePCB/LibrePCB/pull/927>
>
> \## Feature description
> 
> This PR adds a new feature to the schematic- and board… editors; a dialog which allows to directly start ordering the PCB. For details, refer to the discussion about this feature in our forum: https://librepcb.discourse.group/t/ordering-pcbs-directly-from-within-the-application/360
> 
> The feature is intended mainly for users not familiar with the normal ordering process (Gerber/Excellon export, configuring correct export settings, uploading to manufacturers website, ...). But to be honest, I think it is even useful for power users (at least hobbyists), since it is way simpler and faster to order a PCB this way :wink: However, this way you can't choose the manufacturer on your own, at least not yet (the web service can be improved at any time later).
> 
> Beside the practical part of this feature, we hope it also helps to keep the development of LibrePCB ongoing because for each order done through this service, AISLER (the company which will process our orders) will make a donation to the LibrePCB project :heart: 
> 
> \## How it works
> 
> Our server API has been extended with an endpoint for this service. See details \[here\](https://developers.librepcb.org/\_branches/order-pcb-via-api/d1/dcb/doc\_server\_api.html#doc\_server\_api\_resources\_order).
> 
> A new dialog in the schematic- and board editor accesses this API to upload the project as an \*.lppz archive to the API server. Afterwards, the order process needs to be continued in the web browser. This web service is hosted at https://fab.librepcb.org/ (it is also usable by manually uploading the \*.lppz). See details at https://fab.librepcb.org/about.
> 
> \## Screenshots
> 
> The board-and schematic editors contain a new icon in the toolbar, which opens the following dialog.
> 
> \### Before starting the upload
> 
> !\[image\](https://user-images.githubusercontent.com/5374821/137624607-0c28cb8c-3f09-4b15-98ca-6274d18b2ccc.png)
> 
> \### After the upload
> 
> !\[image\](https://user-images.githubusercontent.com/5374821/137624842-e12d93c1-476a-4e57-9d42-33cb83d6b726.png)
> 
> \### The whole workflow
> 
> !\[librepcb-order-pcb-2\](https://user-images.githubusercontent.com/5374821/137625133-d52c8293-0927-44d6-a508-3f565d3301a8.gif)
