Skip to content
Switch branches/tags
Go to file
Cannot retrieve contributors at this time

Fabman API

Welcome! If you're trying to integrate your existing applications and tools with Fabman or create your own application working together with Fabman, you're in the right place!

Everything that can be done via the Fabman web application can be done via the API. If you're not sure how to achieve something, please open a GitHub issue.

The basics

The Fabman API is available via https and expects and returns data in JSON format. Every request URL starts with and most requests require authentication.

Live documentation

You can browse all API endpoints, see required and optional fields and their default values at can even try out every endpoint right in your browser. This is probably the easiest way to experiment and interact with the API.


cURL examples in this documentation can be copy & pasted into a shell prompt to try out requests.


Most requests require authentication. You can use either cookies or API keys for authentication. Both cookies and API keys act as a bearer tokens: anyone who has that cookie or API key can see and change everything you have access to — so you want to guard them as well as you guard your password.

Cookie authentication

The simplest way to authenticate is by obtaining an authentication cookie using your email address and password.

If you're using the interactive documentation page, you can simply sign in via the web form and your browser will automatically use that cookie for all API requests.

You can also obtain it via cURL: First define where you want the cookie to be stored:

export FABMAN_COOKIE=<path to store the cookie>
# for example
export FABMAN_COOKIE=~/.fabman-cookie

Then request a new cookie by POSTing to /user/login:

curl --cookie-jar $FABMAN_COOKIE -H 'Content-Type: application/json' -d '{"emailAddress": "<your email address>", "password": "<your password>"}'

You can use this cookie for any subsequent request by adding the --cookie param:

curl --cookie $FABMAN_COOKIE

API keys

Instead of cookies you can also use an API key token to authenticate your API requests. Every API key belongs to a particular member. Any requests authenticated via an API key are executed as if they were made by the member that the API key belongs to.

API keys don’t expire automatically and remain valid until you delete them.

Creating an API key

There’s no UI for creating API keys yet, but you can create a key via the interactive documentation page. You can then fetch the actual token via GET /api-keys/{id}/token.

If you’ve set up a cURL cookie jar as described above, you can also create an API key via cURL:

curl --cookie $FABMAN_COOKIE -H 'Content-Type: application/json' -d '{"member":"<id of the member to impersonate>"}'

and then fetch the API key token:

curl --cookie $FABMAN_COOKIE{id}/token

Using an API key

Once you have a key, you can send it as a bearer token with the Authorization header:

Authorization: Bearer <your api key token>
# for example
Authorization: Bearer 8d29ff56-b9e3-40b5-9a86-f423fe959b93

You can also send the API key as the username of a basic authentication (without a password). This is convenient when using cURL:

curl -u '<your api key token>:'
# for example
curl -u '8d29ff56-b9e3-40b5-9a86-f423fe959b93:'

Don't forget the colon after the token.

JSON data format

We use JSON for all API data. This means that you have to send the Content-Type header Content-Type: application/json for all POST or PUT requests — otherwise you'll receive a 415 Unsupported Media Type response error.

All data is encoded in UTF-8.


Most collection APIs paginate their results. The first request returns up to 50 records by default, but you can change the page size by specifying a 'limit' query parameter.

The Fabman API follows the RFC5988 convention of using the Link header to provide URLs for the next page. Follow this convention to retrieve the next page of data — please don't build the pagination URLs yourself!

If the Link header is blank, that's the last page. The Fabman API also provides the X-Total-Count header, which displays the total number of resources in the collection you are fetching.

Rate limiting

You can only perform a limited number of requests per second per IP. If you exceed the limit, you'll receive a 429 Too Many Requests response. In such a case wait at least two seconds before retrying a request.

We recommend baking 429 response-handling in to your HTTP handling at a low level so your can handle retries gracefully and automatically.

Create and update entities

Whenever you create a new entity (e.g. by POSTing to a collection endpoint), you can omit any non-required fields to set them to their default values. If you provide additional fields that aren’t expected by the API, you will receive a 400 Bad Request response.

Whenever you update an entity (e.g. by PUTing to the URL of the entity), you can omit any unchanged fields. If you submit any additional or read-only fields that aren’t expected by the API, they’ll be silently ignored. This allows you to GET an entity, change it and submit it without having to filter read-only fields returned by the original GET request.

Optimistic locking

Most entities contain a lockVersion attribute that’s used for optimistic locking. The field is automatically incremented whenever someone updates the entity.

Whenever you want to change such an entity, you must submit the lockVersion field unchanged. If someone else has modified the entity since you last saw it, the update will fail with a 409 Conflict response to avoid unintentionally overwriting their changes. When this happens, you can load the new version of the entity, merge your changes and send another update request.

Rich text content

Many resources such as Members, Equipment, and Packages have attributes that can contain rich text as HTML. Rich text attributes may contain lists, block quotes, links, and simple text formatting.

See the rich text section for details.

Embedding and resolving

Some endpoints allow you to embed related entities into the response to reduce the number of requests needed. For example, when fetching a list of members, you can embed each member's active packages. Otherwise you'd have to send a separate request for each member to determine who currently has which package.

Resolving is a similar technique for reducing the number of requests needed. See the embedding and resolving section for more details.


Fabman’s Webhooks can send a request to an URL (eg, a script on your web server) whenever something happens in Fabman – someone books a machine, updates a member, cancels a package, or switches on a machine. Webhooks let you automate common tasks or develop two-way synchronizations between Fabman and your other systems (eg., CRM, ERP, or public website). Some examples:

  • Update your CRM when someone adds or edits a member.
  • Notify accounting whenever an invoice is created.
  • Apply special discounts when a charge is created.
  • Send an email to the lab manager whenever certain members start working in the lab.


The most important entities are:

Check the live documentation for all available entities and endpoints.


These API docs are licensed under Creative Commons (CC BY-SA 4.0). Please share, remix, and distribute as you see fit.

A big shout-out to the guys at Basecamp. Some sections and lots of inspiration for this documentation was taken from the Basecamp 3 API documentation.

If you have a specific feature request or find a bug, please open a GitHub issue.