KLIQ|Developers

Observations

An observation is the core data unit in the KLIQ AI: a photo captured at a specific location, enriched with metadata and processed by computer vision models.

What is an observation?

An observation consists of:

  • Image — A photo URL (JPEG/PNG, max 20MB)
  • Location — The physical location where the photo was taken
  • Coordinates — GPS latitude and longitude
  • Metadata — Arbitrary key-value pairs (aisle, rep name, etc.)
  • Status — Lifecycle state of the observation

Endpoints

POST/v1/tenants/{tenantId}/observationsCreate a new observation
GET/v1/tenants/{tenantId}/observationsList observations with pagination
GET/v1/tenants/{tenantId}/observations/{id}Get a single observation
DELETE/v1/tenants/{tenantId}/observations/{id}Delete an observation

Creating observations

Single observation

const observation = await tenant.observations.create({
locationId: 'loc_abc123',
imageUrl: 'https://your-bucket.storage.com/shelf.jpg',
latitude: 50.8503,
longitude: 4.3517,
metadata: {
  aisle: 'beverages',
  captured_by: 'rep_jane',
  visit_id: 'visit_xyz',
},
});

console.log(observation.id);     // "obs_abc123"
console.log(observation.status); // "pending"

Batch creation

Submit multiple observations at once for efficiency:

const observations = await tenant.observations.createBatch([
{
  locationId: 'loc_abc123',
  imageUrl: 'https://bucket.com/shelf-1.jpg',
  latitude: 50.8503,
  longitude: 4.3517,
},
{
  locationId: 'loc_abc123',
  imageUrl: 'https://bucket.com/shelf-2.jpg',
  latitude: 50.8503,
  longitude: 4.3517,
},
]);

console.log(`Created ${observations.length} observations`);

Listing and filtering

// List with filters
const page = await tenant.observations.list({
locationId: 'loc_abc123',
status: 'completed',
limit: 50,
});

console.log(page.data);        // Observation[]
console.log(page.cursor.next); // cursor for next page

// Auto-paginate through all results
for await (const obs of tenant.observations.listAll({
locationId: 'loc_abc123',
})) {
console.log(obs.id);
}

Observation statuses

StatusDescription
pendingObservation created, no CV job started
processingCV job is running
completedCV job finished successfully
failedCV job failed

Image upload patterns

Direct URL

Provide a publicly accessible URL to your image. The platform will fetch and store it.

Signed upload

For private images, use the signed upload flow:

// 1. Get a signed upload URL
const { uploadUrl, imageUrl } = await tenant.observations.getUploadUrl({
contentType: 'image/jpeg',
filename: 'shelf-photo.jpg',
});

// 2. Upload directly to cloud storage
await fetch(uploadUrl, {
method: 'PUT',
body: imageBuffer,
headers: { 'Content-Type': 'image/jpeg' },
});

// 3. Create observation with the resulting URL
const obs = await tenant.observations.create({
locationId: 'loc_abc123',
imageUrl: imageUrl,
});

Next steps

  • CV Jobs — Process observations with computer vision
  • Webhooks — Get notified when observations are processed
  • Pagination — Navigate large result sets