Resources
Photos
Photos of a unit's nameplates, labels and overviews. A nameplate or a label is read by AI into suggestions with a confidence for each field. Nothing on the unit changes until the suggestions are saved with the calls for units and components.
The photo model
Properties
-
idstring (uuid) -
unit_idstring (uuid) -
component_idstring (uuid), nullable -
kindstringOne of
nameplate,label,overview -
label_kindstring, nullable -
reading_statusstring, nullablenullwhen the photo is not read.One of
queued,running,done,failed -
taken_atstring (date-time)
The photo reading model
Properties
-
idstring (uuid) -
photo_idstring (uuid) -
statusstringOne of
queued,running,done,failed -
readableboolean, nullable -
fieldsarray -
componentsarray -
service_labelobject, nullable -
modelstring, nullable -
prompt_versionstring -
applied_atstring (date-time), nullable -
created_atstring (date-time)
GET/units/{unit}/photos
List photos
Photos of a unit.
The unit's nameplates, labels and overviews, with the status of each reading. The photos themselves are seen in the app.
Scope: units:read
Path parameters
-
unitstring (uuid) requiredThe ID of the unit.
Query parameters
-
limitintegerRecords per page. At most 100, default 50.
-
cursorstringThe value of
next_cursorfrom the page before.
Response
200 A page of photos. The fields are those of the photo model.
curl https://api.maci.energy/v1/units/0b6f4c1e-5a1d-4a57-9f0e-2f6f3f0c9a11/photos \
-H "Authorization: Bearer $MACI_API_KEY"
const response = await fetch('https://api.maci.energy/v1/units/0b6f4c1e-5a1d-4a57-9f0e-2f6f3f0c9a11/photos', {
headers: {
Authorization: `Bearer ${process.env.MACI_API_KEY}`,
},
});
const data = await response.json();
import os
import requests
response = requests.get(
"https://api.maci.energy/v1/units/0b6f4c1e-5a1d-4a57-9f0e-2f6f3f0c9a11/photos",
headers={"Authorization": f"Bearer {os.environ['MACI_API_KEY']}"},
)
data = response.json()
$client = new \GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.maci.energy/v1/units/0b6f4c1e-5a1d-4a57-9f0e-2f6f3f0c9a11/photos', [
'headers' => [
'Authorization' => 'Bearer '.getenv('MACI_API_KEY'),
],
]);
$data = json_decode($response->getBody(), true);
{
"data": [
{
"id": "4e8a1b2c-3d5f-4a6b-8c9d-0e1f2a3b4c5d",
"unit_id": "0b6f4c1e-5a1d-4a57-9f0e-2f6f3f0c9a11",
"component_id": null,
"kind": "nameplate",
"label_kind": null,
"reading_status": "queued",
"taken_at": "2026-10-30T09:15:00Z"
}
],
"next_cursor": null
}
POST/units/{unit}/photos
Create photo
Send a photo.
A nameplate or a label is read in the background into suggestions. Nothing on the unit changes until the suggestions are saved with the calls for units and components. An overview is never read.
Scope: units:write
Path parameters
-
unitstring (uuid) requiredThe ID of the unit.
Headers
-
Idempotency-KeystringA value of your own choosing, so that a repeated call does not create two records.
Form fields
-
kindstring requiredOne of
nameplate,label,overview -
photostring (binary) requiredJPEG, PNG or WebP of at most 10 MB.
-
label_kindstring, nullableFor a label: which kind.
One of
service,refrigerant,ce,leak_check,other -
component_idstring (uuid), nullableA photo of one of the unit's components.
Response
201 The photo that was saved. The fields are those of the photo model.
curl -X POST https://api.maci.energy/v1/units/0b6f4c1e-5a1d-4a57-9f0e-2f6f3f0c9a11/photos \
-H "Authorization: Bearer $MACI_API_KEY" \
-H "Idempotency-Key: a-value-of-your-own" \
-F "kind=nameplate" \
-F "[email protected]"
const form = new FormData();
form.append('kind', 'nameplate');
form.append('photo', fileInput.files[0]); // nameplate.jpg
const response = await fetch('https://api.maci.energy/v1/units/0b6f4c1e-5a1d-4a57-9f0e-2f6f3f0c9a11/photos', {
method: 'POST',
headers: {
Authorization: `Bearer ${process.env.MACI_API_KEY}`,
'Idempotency-Key': 'a-value-of-your-own',
},
body: form,
});
const data = await response.json();
import os
import requests
response = requests.post(
"https://api.maci.energy/v1/units/0b6f4c1e-5a1d-4a57-9f0e-2f6f3f0c9a11/photos",
headers={"Authorization": f"Bearer {os.environ['MACI_API_KEY']}", "Idempotency-Key": "a-value-of-your-own"},
data={"kind": "nameplate"},
files={"photo": open("nameplate.jpg", "rb")},
)
data = response.json()
$client = new \GuzzleHttp\Client();
$response = $client->request('POST', 'https://api.maci.energy/v1/units/0b6f4c1e-5a1d-4a57-9f0e-2f6f3f0c9a11/photos', [
'headers' => [
'Authorization' => 'Bearer '.getenv('MACI_API_KEY'),
'Idempotency-Key' => 'a-value-of-your-own',
],
'multipart' => [
['name' => 'kind', 'contents' => 'nameplate'],
['name' => 'photo', 'contents' => fopen('nameplate.jpg', 'r')],
],
]);
$data = json_decode($response->getBody(), true);
{
"id": "4e8a1b2c-3d5f-4a6b-8c9d-0e1f2a3b4c5d",
"unit_id": "0b6f4c1e-5a1d-4a57-9f0e-2f6f3f0c9a11",
"component_id": null,
"kind": "nameplate",
"label_kind": null,
"reading_status": "queued",
"taken_at": "2026-10-30T09:15:00Z"
}
GET/photos/{photo}/reading
Get photo reading
What was read on a photo.
The newest reading, with each field's value in SI units, the text it was read from, the confidence (high, medium or low) and where it stands in the photo.
Scope: units:read
Path parameters
-
photostring (uuid) requiredThe ID of the photo.
Response
200 The reading. The fields are those of the photo reading model.
curl https://api.maci.energy/v1/photos/4e8a1b2c-3d5f-4a6b-8c9d-0e1f2a3b4c5d/reading \
-H "Authorization: Bearer $MACI_API_KEY"
const response = await fetch('https://api.maci.energy/v1/photos/4e8a1b2c-3d5f-4a6b-8c9d-0e1f2a3b4c5d/reading', {
headers: {
Authorization: `Bearer ${process.env.MACI_API_KEY}`,
},
});
const data = await response.json();
import os
import requests
response = requests.get(
"https://api.maci.energy/v1/photos/4e8a1b2c-3d5f-4a6b-8c9d-0e1f2a3b4c5d/reading",
headers={"Authorization": f"Bearer {os.environ['MACI_API_KEY']}"},
)
data = response.json()
$client = new \GuzzleHttp\Client();
$response = $client->request('GET', 'https://api.maci.energy/v1/photos/4e8a1b2c-3d5f-4a6b-8c9d-0e1f2a3b4c5d/reading', [
'headers' => [
'Authorization' => 'Bearer '.getenv('MACI_API_KEY'),
],
]);
$data = json_decode($response->getBody(), true);
{
"id": "e7981672-d483-458e-a358-811e2de301c8",
"photo_id": "4e8a1b2c-3d5f-4a6b-8c9d-0e1f2a3b4c5d",
"status": "queued",
"readable": false,
"fields": [
{
"key": "refrigerant",
"value": "Value",
"raw_text": "R449A 42 kg",
"confidence": "high",
"bbox": null
}
],
"components": [
{
"type": "rum-for-varmt",
"fields": [
{
"key": "refrigerant",
"value": "Value",
"raw_text": "R449A 42 kg",
"confidence": "high",
"bbox": null
}
]
}
],
"service_label": null,
"model": "K-100",
"prompt_version": "v3",
"applied_at": null,
"created_at": "2026-10-30T09:15:00Z"
}