The REST API is an HTTP web server commonly referred to as “The API”, “The REST API” or simply “The server”. The REST API handles a number of responsibilities including:

  • Data storage, validation, and security: Allows users to edit information such as sequences and the garden layout even when the device is offline, prevents data loss between factory resets of FarmBot OS by storing the data in the cloud, validates data and controls access to data via authentication and authorization mechanisms.
  • Email delivery: Sends email notifications such as password resets and critical errors to end users. All other messaging is handled by the Message Broker, a distinctly decoupled sub-system of the Web API.
  • Image uploads and manipulation: Re-sizes and stores images captured by FarmBot’s onboard camera.

Generally speaking, the REST API does not control FarmBot. Device control is handled by the Message Broker, CeleryScript, and FarmBot JS.


Web Framework Ruby on Rails
Authorization Mechanism JSON Web Tokens
Deployment Methodology 12 Factor
API Architectural Style REST
Database PostgreSQL
Test Framework RSpec
File Storage Mechanism Google Cloud Storage or filesystem (configurable)
Error Monitoring Rollbar (optional)
Operating System Ubuntu (not configurable)
Continuous Integration System Circle CI (optional)


Resources are JSON documents that can be downloaded from the server and used by FarmBots, humans, and third-party tools to store FarmBot related information. Every resource has a URL, and the HTTP verb used to access the URL will determine how the server handles the request.

As of April 2024, the API manages the following resources:

Resource Description Pagination?
ai_feedbacks Positive/negative reactions to auto-generation prompt results.  
alerts A single item in the message center. Only useful to site administrators. Yes
curves Time-based plant water/height/spread data tables. Yes
device Device account settings.  
farm_events Executes a sequence or regimen based on time. Eg: “Execute this sequence every 6 hours”. Yes
farmware_envs Key/value pairs used for persistent storage. Yes
fbos_config Configuration for FarmBot OS.  
firmware_config Configuration for the Arduino Firmware  
folders Organization for sequences.  
global_bulletins (advanced) An announcement intended for all users of a server  
images Meta data about photos taken by FarmBot.  
logs Messages from a device.  
peripherals Meta data about output hardware. Yes
pin_bindings Bind an I/O pin to sequence execution. Yes
plant_templates A single plant within a saved garden. Not a real plant. Yes
points Represents a saved point on the garden bed. All point types are included in this resource: Plants, Weeds, Tool Slots, and Generic Points.  
point_groups A collection of points based on a criteria or predefined set of points (eg: “All Weeds”, “My Basil Plants” etc..) Yes
regimens Executes sequences based on an offset from the regimen start date. Yes
saved_gardens A pre arranged configuration of plants in a garden. Yes
sensor_readings A single reading from a sensor, recorded to the API. Yes
sensors Meta data about input hardware. Yes
sequence_versions Published versions of sequences for sharing.  
sequences Commands created in the sequence editor.  
telemetries Historical FarmBot OS status information.  
tokens An authorization / authentication secret shared between a user or device and the API.  
tools An physical object that is mounted to the gantry or a tool slot (UTM). Yes
users Device operator data such as registration email.  
web_app_config User interface preferences.  
webcam_feeds Meta data about an external webcam (stream URL) Yes
wizard_step_results Setup wizard result data. Yes

Other endpoints

Endpoint Description
ai Make auto-generation requests.
corpus A glossary of all Celery Script node types in JSON format.
demo_account Create a demo account.
export_data A dump of all the resources listed above.
featured_sequences Promoted publicly shared sequences available for import.
feedback Submit feedback.
global_config Configuration for all users of a server.
password_resets Request password reset.
public_key (advanced) A public encryption key owned by the API server.
releases FarmBot OS releases.
storage_auth (advanced) A policy object for Google Cloud Storage.

Example request

If we wished to change the name of our device to “Carrot Overlord”, we could perform an HTTP PUT to the URL with the following request body:

  "name": "Carrot Overlord"

Such a request would generate the following JSON HTTP response:

  "id": 325,
  "name": "Carrot Overlord",
  "timezone": "America/Curacao",
  "last_saw_api": null,
  "last_saw_mq": null,
  "tz_offset_hrs": -4,
  "fbos_version": null,
  "throttled_until": null,
  "throttled_at": null


Some API endpoints support pagination of GET requests to break the results into smaller “pages” of a fixed length. To make a paginated request, append query strings for page size (eg: per=10) and page number (eg: page=3) to the request.

For example, to download the third page of sensor_readings with a page size of 10 items:


Points endpoint

While the REST API is relatively uniform in how it handles resources, plants, weeds, tool_slots, and generic points fall under the same /api/points endpoint. This endpoint also has some additional capabilities that the other endpoints do not.

Bulk deletion

To delete many point resources in one request, separate the point IDs with a comma:


When points are deleted, it is still possible to view them for 2 months after the time of deletion. This is useful for tools relating to weeding and historical records.


The points endpoint supports a special ?filter= query parameter. There are three options for this parameter:

  • ?filter=all returns archived and active points.
  • ?filter=old only returns archived points.
  • ?filter=kept only returns active (not-archived) points. This is the default behavior for the index endpoint (/api/points).

Generating an API token

You must pass a token string into most HTTP requests under the Authorization request header. Here are some ways in which you can get a token. Also see our web app API examples.

curl -H "Content-Type: application/json" \
     -X POST \
     -d '{"user":{"email":"","password":"password123"}}' \
// Since the API supports [CORS](, you can generate your
// token right in the browser. Here's an example:

    url: "",
    type: "POST",
    data: JSON.stringify({user: {email: '', password: 'password123'}}),
    contentType: "application/json",
    success: function (data) {
                 // You can now use your token:
                 var MY_SHINY_TOKEN = data.token.encoded;
import requests
response = requests.request(
    headers={'content-type': 'application/json'},
    json={'user': {'email': '', 'password': 'password123'}})
TOKEN = response.json()['token']['encoded']

And here’s what the response will look like:

    "token": {
        "unencoded": {
            "iat": 1459109728,
            "bot": "device_456",
            "jti": "922a5a0d-0b3a-4767-9318-1e41ae600352",
            "exp": 1459455328
        // THE IMPORTANT PART IS HERE (shortened for clarity):

The response is provided as JSON for human readability. For your Authorization header, you will only be using data.token.encoded. In this example, it’s the string starting with eyJ0eXAiOiJ...


The API uses JSON Web Tokens for authentication and authorization. Additionally, it uses Content Security Policies to prevent unauthorized access by malicious software on client machines.

What’s next?