Back to top

Beeple API

Welcome to the Beeple API. If you are looking to write an extension for Beeple have a look at our Marketplace.

You can link into our Beeple webhooks to write marketplace applications, but following our webhooks can also be configured in every Beeple installation manually.

If you are a interim office or other entity preparing payroll for staff we provide a payroll API to make sure that everything is legally correct for the employment (in widest sense of the word) of staff.

We also provide integrated APIs for sourcing marketplace integrations.

If you want to manipulate Beeple data as a user (eg. you want to write a specialized mobile app that does exactly one thing) you can use our data management APIs. These manipulate data under a provided use account. To get started, see the authentication guide for instructions on how to obtain and use your API token or OAuth credentials.

General information

Web address

Each tenant (a customer’s own Beeple space) has its own Beeple address. This is the host name used to sign in to the Beeple web application, for example yourcompany.beeple.eu. Beeple finds the tenant from this host name. Send each API request to that address, over HTTPS. The path of the call comes right after the address and starts with /api/v1/:

https://yourcompany.beeple.eu/api/v1/admin/projects

Language code

A language code can be added right after /api/v1/. It is optional:

https://yourcompany.beeple.eu/api/v1/en/admin/projects

When the code is one of the tenant’s languages, such as en, nl or fr, Beeple uses that language. Other codes of two lowercase letters, and codes such as nl-BE, are accepted but ignored. A code in another form, such as eng or EN, gives HTTP 404. Without a code, Beeple uses the language of the API user, then the tenant’s default language, then English.

The language decides which translation of a translated text, such as a project name, is returned, and the language of the messages that Beeple translates. A translated text sent as one plain value, such as the name of a subproject, is saved as the translation in that language.

Calls under /api/v1/incoming/, which are described on the payroll and webhooks pages, do not take a language code.

Headers

Send these headers:

  • Accept: application/json with every request. Without it, some calls answer with an error instead of JSON.

  • Content-Type: application/json when the request has a body. Without it, the body is not read as JSON.

  • Token with an API token, or Authorization: Bearer with an OAuth access token, for the calls that work under a user account. The authentication guide explains how to get them.

The Accept-Version header is optional, but advised for new integrations. It is explained under Versions.

Rate limits

Plan for at most 300 requests per 5 minutes from each IP address. The limit is counted per IP address, not per token or per tenant. API requests and use of the Beeple web application from the same IP address count toward the same limit.

Requests are counted in fixed 5-minute periods that follow the clock, for example from 10:00 to 10:05 and then from 10:05 to 10:10. The count starts again from zero at the start of each period.

Above the limit, Beeple can answer with HTTP status 429 Too Many Requests. This answer is plain text (Retry later), not JSON, and it has no Retry-After header. Beeple rejects the request before handling it, so nothing from it is processed and sending it again later does not create a duplicate. Wait until the next 5-minute period starts (at most 5 minutes), then try again.

Integrations that send their requests from a fixed IP address can ask Beeple support for a higher limit of 900 requests per 5 minutes for that address. The higher limit then applies to all requests from that address, instead of the normal limit.

Versions

The version of the API is part of the path: v1 in /api/v1/. All calls use version 1.

Within version 1, a few calls work differently depending on the optional Accept-Version header, for example Accept-Version: 1.4. The header accepts the values 1.1, 1.2, 1.3 and 1.4. Each value also includes the changes of the lower values. Without the header, or with any other value (for example 1.5 or v1.4), version 1.0 applies. Beeple reads the header on each request, so send it with every request.

What each value changes compared with the value below it:

  • 1.1: when a sign-in with the legacy call POST /api/v1/authenticate (Create Token) fails because of the email, the password or the user account, the answer has a status code that matches the problem. For example, it is 401 for a wrong email or password, 403 for a blocked account or an expired password, and 429 after too many failed sign-in attempts for the same user account. With 1.0 the answer is 200 with "result": false. Only the status code changes.

  • 1.2: a request with the API token or OAuth access token of a blocked user gets 403 instead of 401. Only the status code changes.

  • 1.3: when a subproject is changed with PATCH /api/v1/admin/projects/{project_id}/subprojects/{sub_project_id} (Update subproject), work_location_id and work_location_specification only change when they are sent with a value. Do not send them as null. With lower values, leaving out work_location_id removes the work location of the subproject, and leaving out work_location_specification removes the work location specification in the language of the request.

  • 1.4: when Beeple cannot create a new enrolment sent with POST /api/v1/admin/collaborators/enrolments (Create enrolment), for example because the team is full, the answer is 422 with the fields of the enrolment, including errors and error_overridable. With lower values the answer is 200 with only errors and team_name. Other error answers of this call, for example for missing data in the request, do not change with 1.4.

The header changes nothing else in the documented calls, including the calls under /api/v1/incoming/. It does not change the messages that Beeple sends, such as webhooks, payroll messages and marketplace installation calls.

New integrations are advised to send Accept-Version: 1.4.

Errors

These are the main HTTP status codes that the API uses:

Status Meaning
200, 201, 204 The request worked. Some create calls answer 201. A 204 answer is empty. Some calls also answer 200 when they fail (see the note below the table).
400 A required parameter is missing, the data sent is not valid, or the action is not possible, for example cancelling an enrolment that cannot be cancelled.
401 Beeple did not accept the credentials. For example, the token is missing, not valid or expired, the request comes from an IP address that the token does not allow, or the OTP code for two-factor authentication has not been validated yet.
403 The user is not allowed to do this. From version 1.2, a request with the token of a blocked user also gets 403, see Versions.
404 The record was not found, or the path does not exist. A record that the user is not allowed to see can also give 404.
422 The data sent is not valid. Some calls use 400 for this instead.
429 Too many requests, see Rate limits. From version 1.1, a sign-in with the legacy call also gets 429 after too many failed attempts for the same user account, see Versions. That answer is JSON and is not part of the rate limit.
500 An unexpected error in Beeple.

Some calls answer HTTP 200 even when they fail, so always check whether the answer has an errors or error field that is not empty. With version 1.0, a failed sign-in with the legacy call POST /api/v1/authenticate is one of them, see Versions.

Error answers come in several shapes. The most common ones are:

  • {"errors": {"name": ["can't be blank"]}}: a list of messages for each field that is not valid.

  • {"errors": {"id": "Couldn't find Team with 'id'=123"}}: one message for one field. Most calls answer this way when a record is not found or a required parameter is missing.

  • {"error": "Cancel not allowed"}: one message for the whole request. Some calls use the name errors here, and some send a list of messages.

  • {"status": "Authentication Denied"}: Beeple did not accept the token or the user (401 or 403). A 401 because the OTP code has not been validated has the same shape with another message.

  • {"status": 500, "error": "Internal Server Error"}: the general answer for errors that the call itself does not handle, for example an unexpected error (500), a path that does not exist (404) or a body that is not valid JSON (400). Here status is the status code as a number, and error is the standard name of that code, such as Not Found.

  • The record itself, with an errors field next to its other fields. When the call works, some of these answers still have the errors field, but it is empty ({}). Some enrolment and team answers also have an error_overridable field. When it is true, the errors are only warnings. The request can then be sent again to skip these warnings: for an enrolment with validation_override set to true (see Enrolments), and for a team with skip_overridable_validations set to true (see Teams).

  • No details: an empty answer, an empty object ({}) or plain text. For example, a 403 because the user is not allowed to do something has an empty answer, and the 429 of the rate limit is plain text.

Repeated requests and batches

Beeple does not check whether it has already received the same request. There is no idempotency key (a header that lets a server spot a repeated request). Sending the same create request twice creates two records, unless the second one breaks a rule, for example when it uses an email address that is already in use in the tenant. When a create request times out or gets a 5xx answer, check whether the record exists before sending it again. For the messages that Beeple sends to other systems, see Idempotency on the webhooks page.

None of the documented calls to Beeple is a batch call. Each call that creates, changes or deletes data works on one item, such as one project or one collaborator. A repeating availability counts as one item, so one call can create, change or remove several of its repetitions. To handle many items, send one request for each item.

Generated by aglio on 10 Nov 2026