Limitations
4 min
- Max 60 API calls per minute
- Max. 1,000 API calls per hour
- Max. 24.000 API calls per day
- Max. 5 parallel calls
- Max. 10 GB traffic per month
- Max. 500 records per API call
- Max. 4,000 characters in the filter of an API call
Fair Use Policy
- To ensure that server performance is not affected by overuse of individual users, access to the API for such users can be restricted.
- Prohibited: The API may not be used for any illegal, unethical, or malicious activity. Including but not limited to hacking, spamming or spreading malware.
- Liability: The API owner is not responsible for any damage or loss resulting from the use of the API. Users assume full responsibility for their use of the API and any consequences thereof.
- These guidelines and limitations may be updated at any time. It is the user's responsibility to stay informed of changes.
Remarks
- regarding the limits - programmatically always try to work per bulk request, i.e. programmatically collect/aggregate the data sets and generate a full API query instead of per determined data set (saves calls and is more performant).
- With SaveAll the DataId and EntityId of the created record can be delivered as 200 HTTP code including ReturnText. These can be written back (for orders, any master data, etc.) in order to make direct calls/matches. Accordingly consider the documentation!
- Listing of all entities and their properties can be queried via "GetGenericEntities" and "GetGenericProperties". Only entities with AllowExternalApi set to true are available to other APIs. In general all data get be called by api. If u need other access please contact your consultant. for security reasions this is resctricted like this Your consultant can explain the relationships between the entities.
- Loops with included API calls (general multiple calls) should be avoided.
- The API user may not have rights for most entities. Your consultant needs to know what kind of entities you want to manage via the API so that the correct rights/roles can be set up!
Example
This example creates an API token, retrieves a record, and writes a record including LookupProperty to a table.
# Check this Microsoft documention: https://learn.microsoft.com/de-de/power-bi/connect-data/desktop-python-scripts
import sys
import requests
import pandas as pd
endpoint = "https://test.engine4.io"
endpoint_token = endpoint + "/token"
endpoint_fetchNamed = endpoint + "/webapi/external/fetchNamed"
auth_clientid = "xxx" # Additional factor
auth_user = "[email protected]"
auth_pass = "xxx"
################################## Authenticate ############################################
head = {"Content-Type" : "application/x-www-form-urlencoded"}
body = {"client_id" : auth_clientid, "grant_type": "password", "username" : auth_user , "password" : auth_pass}
# Every request is put in a try-except block to handle connection issues
try:
response = requests.post(endpoint_token, headers=head, data=body)
except requests.RequestException as e:
sys.exit("Error: {0}".format(e))
# Every request expect to be successfull (200), handling errors on others.
response_code = response.status_code
if (response_code==200):
# Every json parsing part is try/excepted.
try:
data = response.json()
except requests.JSONDecodeError as e:
sys.exit("Error: {0}".format(e))
else:
sys.exit("ErrorCode: " + str(response_code) + " - ErrorMessage: " + response.text)
# Retrieve auth data
access_token = data['access_token']
expires_in = data['expires_in']
token_type = data['token_type']
refresh_token = data['refresh_token']
scope = data['scope']
# Generate auth token for further requests
auth_token = token_type + " " + access_token
################################## Get entity 1 ############################################
head = {"Authorization": auth_token, "content-type":"application/json"}
body = {"Identifier":"XXX","Take":100,"Skip":0,"IsActive":1,"Sortings":[]}
# Every request is put in a try-except block to handle connection issues
try:
response = requests.post(endpoint_fetchNamed, headers=head, json=body)
except requests.RequestException as e:
sys.exit("Error: {0}".format(e))
# Every request expect to be successfull (200), handling errors on others.
response_code = response.status_code
if (response_code==200):
try:
data = response.json()
except requests.JSONDecodeError as e:
sys.exit("Error: {0}".format(e))
else:
sys.exit("ErrorCode: " + str(response_code) + " - ErrorMessage: " + response.text)
# We need to know the column names which we're getting from the REST API. These has to be in the DataFrame command. Only flat tables allowed!
# The name of the variable will be the table name in PowerBi
# ColumnName1 and 2 will be the name of the columns in PowerBi
TableName1 = pd.DataFrame(data,columns=['ColumnName1','ColumnName2'],dtype=object)
print(TableName1)
################################## Entity 2 ############################################
head = {"Authorization": auth_token, "content-type":"application/json"}
body = {"Identifier":"XXX","Take":100,"Skip":0,"IsActive":1,"Sortings":[]}
try:
response = requests.post(endpoint_fetchNamed, headers=head, json=body)
except requests.RequestException as e:
sys.exit("Error: {0}".format(e))
response_code = response.status_code
if (response_code==200):
try:
data = response.json()
except requests.JSONDecodeError as e:
sys.exit("Error: {0}".format(e))
else:
sys.exit("ErrorCode: " + str(response_code) + " - ErrorMessage: " + response.text)
TableName2 = pd.DataFrame(data,columns=['ColumnName1'],dtype=object)
print(TableName2)
################################## End ############################################
quit()