Skip to content

API Reference

Welcome! This guide will get you up and running with our API. Our goal is to provide a powerful and intuitive interface that is easy to integrate with.

Our API is designed using an RPC (Remote Procedure Call) style over HTTP. This means that instead of focusing on RESTful resources (nouns), you'll interact with operation-centric methods that represent clear business actions (verbs).

Core Principles

We designed the API with three key principles in mind to make your development experience as smooth as possible.

  • Domain-driven Design: Our API is organized into domain-specific namespaces that logically group related operations. This domain-oriented design simplifies method discovery and ensures that you are always interacting with the correct part of the system.

  • Business Process-Oriented: Our API methods are designed to mirror your real-world business processes. Instead of generic data manipulation, you'll call functions that represent distinct steps in your workflow. For example, you'll call setGreenLotWeight or transferGreenLotToLocation, directly matching the actions your team performs.

  • Data Consistency: To guarantee data integrity, our API treats each business operation as a single, atomic request. This approach bundles all data changes into one call, preventing the data corruption and inconsistencies that can occur when an operation is split across multiple requests.

Request Format

Criteria Description
HTTP MethodOur API exclusively uses the POST HTTP method for all operations. The specific action you wish to perform (e.g., retrieving, creating, or updating data) should be specified within the request body, rather than by using different HTTP verbs like GET, PUT, or DELETE.
Protocol & SecurityAll communication with the API must be made over HTTPS. For security, connections made over unencrypted HTTP will be rejected.
Base URLThe base path for all endpoints is https://api.cropster.com/rpc/v1 where v1 is the current version of the API.
URL Path SchemaThe endpoints are hierarchical structure using dotted namespaces to reflect the business domain. This structure allows for clear organization and easy discovery of endpoints related to specific business operations. The following endpoint naming schema is used for all endpoints: {domain}.{subdomain}.{operation} (e.g., inventory.roast.listRoastedLots).
Content-TypeAll POST requests must include a Content-Type header set to application/json. Requests with a different content type, or without this header, will be rejected. The only exception to this is the OAuth token request, which requires a Content-Type of application/x-www-form-urlencoded.
PayloadRequest and response bodies are in JSON format with camelCase field names. Singular nouns are generally used for fields representing single entities (e.g. locationId). Plural nouns are used for fields representing lists of entities (e.g. greenLots).

Authentication

The Cropster API uses the OAuth 2.0 Client Credentials Grant flow to authenticate all requests. This is a server-to-server authentication method where applications authenticate directly rather than on behalf of a user.

The process involves two main steps which are explained in the following.

Generate API Credentials

Before you can connect to the API, you must create a Service Account in the Cropster user interface to obtain a Client ID and Client Secret.

  1. Log in to your Cropster account and navigate to the Settings > Service Accounts section.
  2. Create a new Service Account.
  3. Assign a name and the required OAuth scopes that define the specific permissions for this account (e.g., inventory.roast to access roast inventory data).
  4. Upon creation, your Client ID and Client Secret will be displayed.
Secure Your Credentials

Your Client Secret is highly sensitive and is only displayed once upon creation. Store it securely and treat it like a password. Do not expose it in client-side code.

Request Access Token

Next, exchange your credentials for a temporary access token by making a POST request against the OAuth2 token endpoint: https://auth.cropster.com/oauth2/token.

Note that the scope parameter must include all OAuth scopes that are required for subsequent API requests. For example, to access roasted inventory data, the inventory.roast scope must be included.

curl -i -X POST \
  https://auth.cropster.com/oauth2/token \
  -H 'Content-Type: application/x-www-form-urlencoded' \
  -d grant_type=client_credentials \
  -d 'client_id=<CLIENT_ID>' \
  -d 'client_secret=<CLIENT_SECRET>' \
  -d scope=inventory.green%20inventory.roast%20inventory.blend

If the request is successful, the response contains the access token that must be set as Bearer: <ACCESS_TOKEN> in the Authorization header of all subsequent API requests.

Successful Response
{
    "access_token": "<ACCESS_TOKEN>",
    "expires_in": 28799,
    "scope": "inventory.green%20inventory.roast%20inventory.blend",
    "token_type": "bearer"
}
Access Token Lifetime

The access token is valid for 8 hours. You should cache the token in your application and reuse it until it expires to reduce latency and avoid unnecessary token requests.


Request Format

This section details the required request format for obtaining an access token and the structure of the response you will receive.

Request Parameters

The following parameters are required for the access token request:

grant_typestring

OAuth grant type must be set to client_credentials.

Example: "client_credentials"
client_idstring

OAuth client ID that was generated when the service account was created.

Example: "<CLIENT_ID>"
client_secretstring

OAuth client secret that was generated when the service account was created.

Example: "<CLIENT_SECRET>"
scopestring

OAuth scopes separated by url-encoded whitespaces (%20). Only scopes that were granted to the service account can be requested here.

Example: "inventory.green%20inventory.roast%20inventory.blend"

Response Fields

A successful request returns the access token along with its associated metadata:

access_tokenstring

OAuth access token that must be used in the Authorization header as Bearer <ACCESS_TOKEN>.

Example: "client_credentials"
expires_ininteger

Lifetime in seconds of the access token.

Example: 28799
scopestring

A string containing the list of permissions granted to the token. Scopes are delimited by a URL-encoded space (%20). Note: To get an array of scopes, you must first URL-decode the string and then split it by the space character.

Example: "inventory.green%20inventory.roast%20inventory.blend"
token_typestring

Type of the issued token. The value is always Bearer.

Example: "Bearer"

Error Handling

Each API request is returning a status code that indicates if the request was successfully completed. In the following, the most common HTTP status codes are listed:

HTTP Status Code Description
200 OKThe request was successful.
400 Bad RequestThe request couldn't be processed by the server due to an invalid request. Possible reasons can be missing or invalid query parameters, invalid JSON payload or malformed URL.
401 UnauthorizedThe provided authentication credentials are not correct. Please check the section Authentication on how to provide valid authentication credentials.
403 ForbiddenThe client doesn't have permissions to perform the request. Please check the endpoint documentation on which permissions are required.
405 Method Not AllowedThis error indicates that the requested operation is not supported. For example, this error can be caused when a POST request is not supported by an endpoint.
422 Unprocessable EntityThe request failed due to semantic errors in the request body. Examples of semantic errors are missing attributes or the violation of business rules (e.g. creating a green lot with a negative weight).
429 Too Many RequestsThe client has sent too many requests in a given amount of time. Please check the Rate Limiting section for more details.
500 Server ErrorAn internal error encountered within Cropster. Please check the Cropster status page to verify if all systems are operational.

To handle errors programmatically, each error response contains one of the following error codes:

Error Code Description
invalid_authenticationIndicates that the authentication credentials provided are invalid. For example, the JWT is missing or is expired.
access_deniedIndicates that the user is authenticated but does not have the required permissions to access the requested resource. For example, a user without the appropriate role attempts to perform a restricted operation.
resource_not_foundIndicates that the specified resource could not be found. For example, an object is request by an ID that does not exist.
invalid_weightIndicates that the weight parameter in the request is invalid. For example, a negative weight amount is specified.
invalid_priceIndicates that the price parameter in the request is invalid. For example, a negative price amount is provided.
invalid_parameterA general-purpose error indicating that one or more parameters in the request failed validation. This is a fallback error and should include a descriptive message with more detail. Note, this error should not normally be returned unless a more specific code is not applicable.
missing_parameterIndicates that a required parameter is missing from the request. For example, the name property is omitted in the importGreenLot request.
unsupported_currencyIndicates that the specified currency is not an ISO 8601 compliant currency code.
unsupported_unitIndicates that the specified weight unit is not supported. Only KG and LBS are currently accepted.
too_many_requestsIndicates that the client has sent too many requests in a given amount of time.
server_errorIndicates an internal server error occurred while processing the request. The accompanying error message should provide additional context.

Pagination

The RPC API uses cursor-based pagination for read-centric, listing endpoints. The results are delivered in reverse-chronological order. This means that the most recently created results appear first in the result set. For the time being, only forward navigation is supported. The default page size is set to 50 items per page.

The meta.pagination.endCursor field in the response indicates if there are more pages. Pass this cursor value in the params.pagination.after field of the next request to retrieve the next page. If there are no further pages, meta.pagination.endCursor will be null.


Pagination Request Parameters

params.pagination.afterstring

Cursor value to retrieve the result of the next page. This value is obtained from the meta.pagination.endCursor field of the previous response. If not specified or null, the first page of results is returned.

params.pagination.limitint[ 1 .. 100 ]

Specifies the page size of the result set. The value must be in the range between 1 and 100. If not specified, the default value of 50 is used.

Pagination Response Field

meta.pagination.endCursorstring

Cursor value to retrieve the records of the next page. This value should be passed in the params.pagination.after field of the next request. If there are no further pages, this value is null.

Example

In the following the pagination mechanism is explained using the inventory.roast.listRoastedLots endpoint as an example. The first request retrieves the first page of roasted lots created after 2025-01-01T00:00:00Z with a page size of 10 records. Notice, the after field is set to null to indicate that the first page should be returned.

First request to retrive first page
POST <BASE_PATH>/inventory.roast.listRoastedLots
Content-type: application/json
Authorization: Bearer <TOKEN>
{
    "params": {
        "filter": {
            "roastedDate": {
                "from": "2025-01-01T00:00:00Z"
            }
        },
        "pagination": {
            "after": null,
            "limit": 10 
        }
    }
}

The response of the above request contains the meta.pagination.endCursor field that can be used to retrieve the next page. This value should be passed in the params.pagination.after field of the next request. If there are no further pages, meta.pagination.endCursor will be null.

Paginated response
 {
  "ok": true,
  "result": {
    "roasts": [
      ...
    ]
  },
  "meta": {
    "pagination": {
      "endCursor": 
        "aBc="
    }
  }
}

Since an endCursor value of aBc= was returned in the previous response, there are more pages available. To retrieve the next page, use this value in the params.pagination.after field in the next request.

Second request to retrieve the next page
POST <BASE_PATH>/inventory.roast.listRoastedLots
Content-type: application/json
Authorization: Bearer <TOKEN>
{
    "params": {
        "filter": {
            "roastedDate": {
                "from": "2025-01-01T00:00:00Z"
            }
        },
        "pagination": {
            "after": "aBc=
        }
    }
}

Rate Limiting

To ensure fair usage and maintain optimal performance of the API, rate limiting is enforced on all endpoints. If a client exceeds the specified limits, the API will respond with an 429 Too Many Requests HTTP status code.

Our standard rate limits are set as follows:

  • Rate Limit: 5 requests per second. This is the average throughput your application is allowed to execute.

  • Burst Limit: 10 requests per second. Allows for short-term spikes in traffic. For example, your application can send up to 10 requests in a single, as long as the average rate remains within the 5 req/sec sustained limit.

Versioning

Our API is versioned to ensure that your integration remains stable and that future updates do not introduce breaking changes unexpectedly. We use URI path versioning, where the version is explicitly included in the request path.

  • Current Version: The current stable version of our API is v1.

  • Future Versions: When we introduce backward-incompatible changes, we will release a new API version (e.g., v2, v3). Older versions are supported for a reasonable time, with a clear migration guide provided well in advance of retirement.

Languages
Servers

https://api.cropster.com/rpc/v1/

Green

The inventory.green namespace contains all operations for managing your green lots.

With this API, you can:

  • Import green lots from your ERP system to Cropster.
  • Transfer green inventory to another location.
  • Make weight adjustments to existing green lots.
  • Retrieve the existing green lots from you inventory.
Operations

Request

Retrieves a list of green lots from the inventory.

Security
oauth2
Bodyapplication/jsonrequired
paramsobject
filterobject

Defines all required and optional filter parameters for the operation.

paginationobject

Defines all required and optional pagination parameters for the operation.

limitinteger(int32)[ 1 .. 100 ]

The number of elements to be returned

Default 50
Example: 20
afterstring

The cursor to retrieve the next page. This is an opaque value that should not be interpreted by the client.

Example: "aBc="
curl -i -X POST \
  https://api.cropster.com/rpc/v1/inventory.green.listGreenLots \
  -H 'Authorization: Bearer <YOUR_TOKEN_HERE>' \
  -H 'Content-Type: application/json' \
  -d '{
    "params": {
      "filter": {},
      "pagination": {
        "limit": 20,
        "after": "aBc="
      }
    }
  }'

Responses

OK

Bodyapplication/json
okboolean

Indicates whether the request was successful.

Example: true
resultobject

Contains the response data of a successful request.

greenLotsArray of objects
idstring(uuid)

The unique identifier of the green lot.

Example: "550e8400-e29b-41d4-a716-446655440000"
namestring

The name of the green lot.

Example: "Ethiopia Natural"
icoNumberstring

The ICO (International Coffee Organization) number associated with the green lot.

Example: "5412"
externalIdstring

Represents the unique identifier of the imported green lot in an external system (e.g. ERP).

Example: "green-lot-9876"
weightobject

Represents the current weight of the object.

priceobject

Represents a price with an amount and a currency.

locationobject

Represents the relationship between an internal object and its external identifier.

metaobject

Contains the metadata (e.g. pagination information) of the response.

paginationobject

Represents the pagination fields of the response.

endCursorstring

Cursor value to retrieve the records of the next page. If there no further pages, this value is null.

Example: "aBc="
Response
application/json
{ "ok": true, "result": { "greenLots": [ { "id": "550e8400-e29b-41d4-a716-446655440000", "name": "Ethiopia Natural", "icoNumber": "5412", "externalId": "green-lot-9876", "weight": { "amount": 12.5, "unit": "KG" }, "price": { "amount": 25.5, "currency": "USD" }, "location": { "id": "550e8400-e29b-41d4-a716-446655440000", "externalId": "location-1234" } } ] }, "meta": { "pagination": { "endCursor": "aBc=" } } }

Request

Imports a new green lot from an external system (e.g. ERP) into Cropster by an external identifier (= externalId). Optionally, providing the warehouse via location is possible, by setting the location.externalId property.

Security
oauth2
Bodyapplication/jsonrequired
dataobject

Defines the data required for the operation, including all mandatory and optional fields.

namestringrequired

The name of the imported green lot

Example: "Ethiopia Natural"
icoNumberstring

The ICO (= International Coffee Organization) number associated with the green lot

Example: "5412"
externalIdstringrequired

Represents the unique identifier of the imported green lot in an external system (e.g. ERP).

Example: "green-lot-9876"
weightobjectrequired

Represents the current weight of the object.

amountnumber(double)decimal places <= 3required

The weight amount represented as floating-point number.

Example: 12.5
unitstringrequired

The weight unit of the object.

Enum"KG""LBS"
Example: "KG"
priceobject

Represents a price with an amount and a currency.

amountnumberdecimal places <= 2required

The price amount represented as floating-point number.

Example: 25.5
currencystring= 3 charactersrequired

The currency of the price, represented as ISO 4217 currency code.

Example: "USD"
locationobject

Represents the relationship between an internal object and its external identifier.

externalIdstring

Represents the unique identifier of this object in an external system (e.g. ERP).

Example: "location-1234"
curl -i -X POST \
  https://api.cropster.com/rpc/v1/inventory.green.importGreenLot \
  -H 'Authorization: Bearer <YOUR_TOKEN_HERE>' \
  -H 'Content-Type: application/json' \
  -d '{
    "data": {
      "name": "Ethiopia Natural",
      "icoNumber": "5412",
      "externalId": "green-lot-9876",
      "weight": {
        "amount": 12.5,
        "unit": "KG"
      },
      "price": {
        "amount": 25.5,
        "currency": "USD"
      },
      "location": {
        "externalId": "location-1234"
      }
    }
  }'

Responses

OK

Bodyapplication/json
okboolean

Indicates whether the request was successful.

Example: true
resultobject

Contains the response data of a successful request.

greenLotobject

Represents a lot of green coffee beans.

idstring(uuid)

The unique identifier of the green lot.

Example: "550e8400-e29b-41d4-a716-446655440000"
namestring

The name of the green lot.

Example: "Ethiopia Natural"
icoNumberstring

The ICO (International Coffee Organization) number associated with the green lot.

Example: "5412"
externalIdstring

Represents the unique identifier of the imported green lot in an external system (e.g. ERP).

Example: "green-lot-9876"
weightobject

Represents the current weight of the object.

priceobject

Represents a price with an amount and a currency.

locationobject

Represents the relationship between an internal object and its external identifier.

Response
application/json
{ "ok": true, "result": { "greenLot": { "id": "550e8400-e29b-41d4-a716-446655440000", "name": "Ethiopia Natural", "icoNumber": "5412", "externalId": "green-lot-9876", "weight": { "amount": 12.5, "unit": "KG" }, "price": { "amount": 25.5, "currency": "USD" }, "location": { "id": "550e8400-e29b-41d4-a716-446655440000", "externalId": "location-1234" } } } }

Roast

Currently, the inventory.roast namespace allows you to retrieve roasted lots from your inventory.

Operations

Blend

Currently, the inventory.blend namespace allows you to retrieve blended lots from your inventory.

Operations