Skip to main content

API Interface

Overview​

Additionally, the REST API can be used as an API export – it gives you the ability to retrieve your inspection equipment data from memida at any time. You decide when, how often, and which data you export – individual inspection equipment, entire lists, or specifically documents such as calibration certificates and inspection protocols.

While the JSON export and the VDI 2623 export provide the entire data inventory as a ZIP archive, the API offers selective access in real time, without daily limits.


Prerequisites​

For an export via the API, you must have the API enabled in your plan. For a detailed guide on how to use the REST API, please refer to our API Reference.


Practical Examples​

The following examples show typical export scenarios. Expand an example to see the complete code.

Export all inspection equipment (Bash / cURL)

This script reads all inspection equipment page by page from the API and saves them to a JSON file.

#!/bin/bash
# Export all inspection equipment via the API

API_KEY="live XXXXXXXXXXXXXXXXXXXXXXX"
BASE_URL="https://api.memida.de"
OUTPUT_FILE="apparatuses_export.json"
PAGE=1
LIMIT=100
ALL_DATA="[]"

while true; do
RESPONSE=$(curl -s \
-H "Auth: $API_KEY" \
-H "Accept: application/json" \
"$BASE_URL/api/v1/apparatuses?limit=$LIMIT&page=$PAGE")

# Extract data from the response
DATA=$(echo "$RESPONSE" | jq '.data')
PAGE_COUNT=$(echo "$RESPONSE" | jq '.paginator.pageCount')

# Merge data
ALL_DATA=$(echo "$ALL_DATA $DATA" | jq -s '.[0] + .[1]')

echo "Page $PAGE of $PAGE_COUNT exported"

# Check if last page reached
if [ "$PAGE" -ge "$PAGE_COUNT" ]; then
break
fi

PAGE=$((PAGE + 1))
done

echo "$ALL_DATA" | jq '.' > "$OUTPUT_FILE"
echo "Export completed: $(echo "$ALL_DATA" | jq 'length') inspection equipment in $OUTPUT_FILE"
Retrieve single inspection equipment with inspection history (Python)

Retrieves an inspection equipment by its identification number – including inspections, test plans and comments.

import requests

API_KEY = "live XXXXXXXXXXXXXXXXXXXXXXX"
BASE_URL = "https://api.memida.de"
IDENTNO = "PM-2024-001"

headers = {
"Auth": API_KEY,
"Accept": "application/json"
}

response = requests.get(
f"{BASE_URL}/api/v1/apparatuses/identno/{IDENTNO}",
headers=headers
)

if response.status_code == 200:
apparatus = response.json()["data"]

print(f"Equipment: {apparatus['apparatus_fullname']}")
print(f"Status: {apparatus['status']}")
print(f"Ident no.: {apparatus['identno']}")
print(f"Serial no.: {apparatus.get('serial_number', '–')}")
print(f"Next inspection: {apparatus.get('next_check_at', '–')}")

for inspection in apparatus.get("inspections", []):
result = inspection["inspection_result"]["name"]
checked = inspection["checked_at"]
insp_type = inspection.get("inspection_type", {})
type_name = insp_type.get("name", "–") if insp_type else "–"
print(f" Inspection: {type_name} on {checked} → {result}")

elif response.status_code == 404:
print(f"Inspection equipment with ident no. '{IDENTNO}' not found.")
else:
print(f"Error: {response.status_code}")

Example output:

Equipment:       Druck DPI 620 Multifunction Pressure Calibrator
Status: operational
Ident no.: PM-2024-001
Serial no.: SN-123456
Next inspection: 2026-06-15
Inspection: DAkkS Calibration on 2025-06-14T09:00:00+02:00 → operational
Identify due inspection equipment (Python)

Identifies all inspection equipment whose next inspection date is within the next 30 days – e.g. for audit preparation.

import requests
from datetime import datetime, timedelta

API_KEY = "live XXXXXXXXXXXXXXXXXXXXXXX"
BASE_URL = "https://api.memida.de"
DAYS_AHEAD = 30

headers = {
"Auth": API_KEY,
"Accept": "application/json"
}

today = datetime.now().date()
deadline = today + timedelta(days=DAYS_AHEAD)

page = 1
due_items = []

while True:
response = requests.get(
f"{BASE_URL}/api/v1/apparatuses",
headers=headers,
params={"limit": 100, "page": page}
)
data = response.json()

for apparatus in data["data"]:
next_check = apparatus.get("next_check_at")
if next_check and apparatus.get("checkup"):
check_date = datetime.strptime(next_check, "%Y-%m-%d").date()
if today <= check_date <= deadline:
due_items.append({
"identno": apparatus["identno"],
"name": apparatus["apparatus_fullname"],
"next_check_at": next_check,
"days_remaining": (check_date - today).days
})

paginator = data["paginator"]
if page >= paginator["pageCount"]:
break
page += 1

due_items.sort(key=lambda x: x["days_remaining"])

print(f"\n{len(due_items)} inspection equipment due within the next {DAYS_AHEAD} days\n")
for item in due_items:
print(f" [{item['days_remaining']:3d} days] {item['identno']:<15} {item['name']}")

Example output:

======================================================================
3 inspection equipment due within the next 30 days
======================================================================

[ 5 days] PM-2024-017 Fluke 8588A Digital Multimeter
[ 12 days] PM-2024-003 Endress+Hauser Promag P300 Flow Meter
[ 28 days] PM-2024-042 Mettler Toledo XPR205 Analytical Balance
Download calibration certificates (Python)

Downloads all inspection documents (calibration certificates, protocols) of a specific inspection equipment.

import os
import requests

API_KEY = "live XXXXXXXXXXXXXXXXXXXXXXX"
BASE_URL = "https://api.memida.de"
APPARATUS_ID = "3fa85f64-5717-4562-b3fc-2c963f66afa6"
DOWNLOAD_DIR = "./calibration_certificates"

headers = {
"Auth": API_KEY,
"Accept": "application/json"
}

response = requests.get(
f"{BASE_URL}/api/v1/apparatuses/{APPARATUS_ID}",
headers=headers
)
apparatus = response.json()["data"]

os.makedirs(DOWNLOAD_DIR, exist_ok=True)

print(f"Downloading documents for: {apparatus['apparatus_fullname']}")

# Download device files
if apparatus.get("files"):
files = apparatus["files"] if isinstance(apparatus["files"], list) else [apparatus["files"]]
for file_info in files:
file_response = requests.get(
f"{BASE_URL}/api/v1/files/{file_info['id']}",
headers={"Auth": API_KEY}
)
if file_response.status_code == 200:
filepath = os.path.join(DOWNLOAD_DIR, file_info["name"])
with open(filepath, "wb") as f:
f.write(file_response.content)
print(f" ✓ {file_info['name']}")

# Download inspection files (calibration certificates etc.)
for inspection in apparatus.get("inspections", []):
for file_info in inspection.get("files", []):
file_response = requests.get(
f"{BASE_URL}/api/v1/files/{file_info['id']}",
headers={"Auth": API_KEY}
)
if file_response.status_code == 200:
filepath = os.path.join(DOWNLOAD_DIR, file_info["name"])
with open(filepath, "wb") as f:
f.write(file_response.content)
print(f" ✓ {file_info['name']}")

print(f"\nAll documents saved in '{DOWNLOAD_DIR}'.")
CSV export for Excel (Python)

Exports all inspection equipment as a CSV file that can be opened directly in Excel.

import csv
import requests

API_KEY = "live XXXXXXXXXXXXXXXXXXXXXXX"
BASE_URL = "https://api.memida.de"
OUTPUT_FILE = "inspection_equipment_export.csv"

headers = {
"Auth": API_KEY,
"Accept": "application/json"
}

CSV_COLUMNS = [
"identno", "apparatus_fullname", "serial_number",
"manufacturer_name", "status", "costcenter_name",
"next_check_at", "latest_checked",
"check_interval", "interval_unit", "apparatus_type_names",
]

page = 1
all_rows = []

while True:
response = requests.get(
f"{BASE_URL}/api/v1/apparatuses",
headers=headers,
params={"limit": 100, "page": page, "sort": "identno", "direction": "asc"}
)
data = response.json()

for apparatus in data["data"]:
row = {col: apparatus.get(col, "") for col in CSV_COLUMNS}
all_rows.append(row)

paginator = data["paginator"]
if page >= paginator["pageCount"]:
break
page += 1

with open(OUTPUT_FILE, "w", newline="", encoding="utf-8-sig") as f:
writer = csv.DictWriter(f, fieldnames=CSV_COLUMNS, delimiter=";")
writer.writeheader()
writer.writerows(all_rows)

print(f"CSV export completed: {len(all_rows)} inspection equipment in '{OUTPUT_FILE}'")

Tip: The utf-8-sig encoding and the semicolon as delimiter ensure that the file opens correctly in Microsoft Excel with umlauts and proper column separation.

Inspection equipment status summary (JavaScript / Node.js)
const API_KEY = "live XXXXXXXXXXXXXXXXXXXXXXX";
const BASE_URL = "https://api.memida.de";

async function fetchStatusSummary() {
const statusCount = {};
let page = 1;
let totalPages = 1;

while (page <= totalPages) {
const response = await fetch(
`${BASE_URL}/api/v1/apparatuses?limit=100&page=${page}`,
{
headers: {
"Auth": API_KEY,
"Accept": "application/json"
}
}
);

const json = await response.json();
totalPages = json.paginator.pageCount;

for (const apparatus of json.data) {
const status = apparatus.status;
statusCount[status] = (statusCount[status] || 0) + 1;
}

page++;
}

console.log("\nInspection Equipment Status Overview:");
console.log("─".repeat(40));

const total = Object.values(statusCount).reduce((a, b) => a + b, 0);

for (const [status, count] of Object.entries(statusCount).sort((a, b) => b[1] - a[1])) {
const pct = ((count / total) * 100).toFixed(1);
console.log(` ${status.padEnd(22)} ${String(count).padStart(5)} (${pct}%)`);
}

console.log("─".repeat(40));
console.log(` ${"Total".padEnd(22)} ${String(total).padStart(5)}`);
}

fetchStatusSummary();

Example output:

Inspection Equipment Status Overview:
────────────────────────────────────────
operational 285 (82.1%)
not_operational 23 (6.6%)
locked 18 (5.2%)
out_of_house 12 (3.5%)
decommissioned 9 (2.6%)
────────────────────────────────────────
Total 347

Notes​

  • Your data, your access: The API is available to you without daily export limits. You can retrieve your data as often and to the extent you need.
  • Date formats: All timestamps follow ISO 8601 (e.g. 2026-02-11T14:30:00+01:00). Pure date fields use YYYY-MM-DD.
  • Encoding: All responses are UTF-8 encoded.
  • Documents: Calibration certificates, inspection protocols and other files are delivered via /api/v1/files/{file_id} as binary data with the appropriate Content-Type.
  • Complete reference: The detailed description of all fields, status values and inspection results can be found in the API Reference.