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/jsonwith every request. Without it, some calls answer with an error instead of JSON. -
Content-Type: application/jsonwhen the request has a body. Without it, the body is not read as JSON. -
Tokenwith an API token, orAuthorization: Bearerwith 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 callPOST /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 is401for a wrong email or password,403for a blocked account or an expired password, and429after too many failed sign-in attempts for the same user account. With 1.0 the answer is200with"result": false. Only the status code changes. -
1.2: a request with the API token or OAuth access token of a blocked user gets403instead of401. Only the status code changes. -
1.3: when a subproject is changed withPATCH /api/v1/admin/projects/{project_id}/subprojects/{sub_project_id}(Update subproject),work_location_idandwork_location_specificationonly change when they are sent with a value. Do not send them asnull. With lower values, leaving outwork_location_idremoves the work location of the subproject, and leaving outwork_location_specificationremoves the work location specification in the language of the request. -
1.4: when Beeple cannot create a new enrolment sent withPOST /api/v1/admin/collaborators/enrolments(Create enrolment), for example because the team is full, the answer is422with the fields of the enrolment, includingerrorsanderror_overridable. With lower values the answer is200with onlyerrorsandteam_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 nameerrorshere, and some send a list of messages. -
{"status": "Authentication Denied"}: Beeple did not accept the token or the user (401or403). A401because 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). Herestatusis the status code as a number, anderroris the standard name of that code, such asNot Found. -
The record itself, with an
errorsfield next to its other fields. When the call works, some of these answers still have theerrorsfield, but it is empty ({}). Some enrolment and team answers also have anerror_overridablefield. When it istrue, the errors are only warnings. The request can then be sent again to skip these warnings: for an enrolment withvalidation_overrideset totrue(see Enrolments), and for a team withskip_overridable_validationsset totrue(see Teams). -
No details: an empty answer, an empty object (
{}) or plain text. For example, a403because the user is not allowed to do something has an empty answer, and the429of 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.