WaterMeter AI

API OCR per contatori dell’acqua

API OCR per contatori dell’acqua. Questa pagina documenta l'API HTTP pubblica esposta dal backend del sito per integrazioni di terze parti.

Inizia con un caricamento reale

Registrati, carica la tua foto del contatore dell’acqua nel workspace e poi crea una chiave API quando sei pronto per l’integrazione.

Panoramica

  • Usa il backend del sito per tutte le integrazioni esterne.
  • Non chiamare waterMeterAi direttamente da programmi di terze parti.
  • L'Open API condivide utenti, quote, cache, attività e regole di audit con il portale web.
  • Il backend può indirizzare diverse attività IA downstream in base alla configurazione di deployment.
  • Le risposte delle attività ora includono un oggetto result_summary generico, così business diversi possono mostrare tipi di risultato diversi.

Autenticazione

  • Accedi al sito e crea una chiave API nella pagina Chiavi API.
  • La chiave API completa viene mostrata una sola volta al momento della creazione.
  • Invia la chiave nell'header Authorization in ogni richiesta.
Authorization: Bearer wm_xxxxxxxxxxxxxxxxx

API Key Permissions and Limits

  • Each API key can have independent scopes, an IPv4/IPv6/CIDR allowlist, a total requests-per-minute limit, and a task submissions-per-minute limit.
  • A valid key without the required scope or outside its source IP allowlist returns 403.
  • Every valid-key request consumes the total request limit, including requests rejected by scope, IP, or submission policy.
  • Batch requests consume one total request unit and one submission unit per uploaded file.
  • Rate-limited responses return 429 with Retry-After and both X-RateLimit-* and X-SubmissionLimit-* headers.
  • Task creation also has a per-key concurrency limit and returns X-ConcurrencyLimit-* headers; a concurrency rejection uses 429.
  • For batch concurrency, only files that pass image validation reserve slots, and success headers report the actual active slots after task binding.
Retry-After: 30
X-RateLimit-Limit: 60
X-RateLimit-Remaining: 59
X-RateLimit-Reset: 1785902400
X-SubmissionLimit-Limit: 10
X-SubmissionLimit-Remaining: 9
X-ConcurrencyLimit-Limit: 3
X-ConcurrencyLimit-Active: 1
X-ConcurrencyLimit-Remaining: 2

Regole di caricamento

  • Dimensione massima file: 20 MB per immagine.
  • Formati supportati: JPEG, PNG, WEBP.
  • Il backend valida il contenuto reale del file, non solo l'estensione.

Carica applicazione delle dimensioni

  • I caricamenti in batch accettano fino a 8 immagini per impostazione predefinita, con un limite di 20 MB per immagine e un limite di contenuto file totale di 20 MB.
  • Un file o un batch che supera il limite restituisce 413 prima della convalida dell'immagine o della creazione dell'attività; non viene creato alcun lotto parziale.
  • Il backend applica il conteggio effettivo dei byte ricevuti anche quando manca Content-Length o viene utilizzato il trasferimento in blocchi.

Stati attività

  • queued: accettata e in attesa di elaborazione IA.
  • running: attualmente in elaborazione, oppure già passata al dispatcher e ancora in polling per il risultato finale.
  • batch_waiting_ai: ogni elemento del batch attende che il servizio IA torni online.
  • batch_running: il batch è già stato passato al dispatcher ed è ancora in elaborazione.
  • done: completata con successo.
  • failed: elaborazione non riuscita.
  • waiting_ai: in coda finché il servizio IA non torna online, poi riprende automaticamente.

Origini risultato

  • fresh: generato da una nuova esecuzione IA.
  • cached_exact: corrisponde alla cache della versione IA corrente.
  • cached_stale: IA offline, restituito l'ultimo risultato in cache.
  • pending: nessun risultato finale disponibile.
  • failed: attività non riuscita.
  • Quando un'attività non è ancora conclusa, controlla error_message per l'ultimo motivo di retry o attesa.

Quota e fatturazione

  • Usa `GET /api/open/quota` prima di inviare carichi di lavoro grandi se l’integrazione deve evitare errori di quota.
  • Solo le esecuzioni AI `fresh` consumano quota.
  • I risultati `cached_exact`, `cached_stale`, `pending` e `failed` non consumano quota.
  • Gli account gratuiti usano prima la quota giornaliera. Gli account a pagamento usano i pacchetti di quota periodica attivi, poi quota temporanea o fissa secondo la policy del backend.
  • Quando la quota è esaurita, l’invio della task restituisce `429` e un messaggio di errore invece di creare una nuova task.

Cache e aggiornamento dei risultati

  • Il backend memorizza nella cache i risultati riusciti per hash immagine e versione AI, incluso il namespace del business downstream.
  • `cached_exact` significa che la stessa immagine ha già un risultato riuscito per la versione AI corrente, quindi non è stata necessaria una nuova esecuzione AI.
  • `cached_stale` significa che il servizio AI è offline e il backend ha restituito l’ultimo risultato storico disponibile.
  • Quando `is_latest_ai_version` è false, conserva il risultato come dato storico utilizzabile ma da rivedere.
  • Non presumere che ogni task `done` abbia consumato quota; controlla `result_source`.

Task completion webhooks

  • Send signed task completion events to your HTTPS endpoint with automatic retries.
  • This API key is inactive. Existing records remain available, but new, enabled, test, and secret-rotation operations are blocked.
X-WaterMeter-Webhook-Id: whev_new_event
X-WaterMeter-Webhook-Replay-Of: whev_original_event
replay_of_event_id: whev_original_event
blocked endpoint management: HTTP 409
canceled delivery status: canceled

GET/api/open/quota

Leggi la quota corrente e l'utilizzo rimanente.

Esempio di richiesta
curl -X GET "https://watermeterai.com/api/open/quota" \
  -H "Authorization: Bearer wm_xxxxxxxxxxxxxxxxx"
Esempio di risposta
{
  "ok": true,
  "email": "[email protected]",
  "quota": {
    "account_type": "free",
    "daily_limit": 20,
    "used": 3,
    "remaining": 17,
    "day_tag": "2026-06-01",
    "is_unlimited": false,
    "monthly_remaining": 0,
    "monthly_bonus_remaining": 0,
    "fixed_remaining": 0,
    "nearest_expire_at": null,
    "quota_summary_text": "Free daily quota: 3/20 used today. Remaining: 17."
  }
}

GET/api/open/ai-status

Leggere lo stato del servizio pubblico per l'invio delle attività e il fallback dei risultati memorizzati nella cache.

Esempio di richiesta
curl -X GET "https://watermeterai.com/api/open/ai-status" \
  -H "Authorization: Bearer wm_xxxxxxxxxxxxxxxxx"
Esempio di risposta
{
  "ok": true,
  "is_online": true,
  "busy": false,
  "active_jobs": 0,
  "public_status": "online",
  "public_status_label": "online",
  "public_status_reason": "ready",
  "accepts_new_tasks": true,
  "can_return_cached_result": true,
  "queue_state": "idle",
  "queue_count": 0,
  "current_ai_version": "water_v2:wm-ai-v2-2026-06-01",
  "last_checked_at": "2026-06-01T06:15:30Z"
}

POST/api/open/tasks

Carica un'immagine e crea una singola attività.

Esempio di richiesta
curl -X POST "https://watermeterai.com/api/open/tasks" \
  -H "Authorization: Bearer wm_xxxxxxxxxxxxxxxxx" \
  -F "file=@D:\data\meter_001.jpg"
Esempio di risposta
{
  "ok": true,
  "task_id": "8e6c4d1f8f8348c0bc53e2e39d2dc111",
  "status": "queued",
  "result_source": "pending",
  "visibility": "private",
  "ai_online": true,
  "is_latest_ai_version": false,
  "final_reading": "-",
  "result_summary": {
    "resultKind": "unknown",
    "primaryLabel": "Result",
    "primaryValue": "-",
    "secondaryLabel": "Detail",
    "secondaryValue": "-",
    "summaryText": "No result is available yet."
  },
  "error_message": "",
  "created_at": "2026-06-01T06:16:10Z"
}

GET/api/open/tasks/{task_id}

Leggi lo stato di un'attività e la lettura finale.

Esempio di richiesta
curl -X GET "https://watermeterai.com/api/open/tasks/task_a" \
  -H "Authorization: Bearer wm_xxxxxxxxxxxxxxxxx"
Esempio di risposta
{
  "ok": true,
  "task_id": "8e6c4d1f8f8348c0bc53e2e39d2dc111",
  "status": "done",
  "result_source": "fresh",
  "ai_online": true,
  "is_latest_ai_version": true,
  "final_reading": "123.45",
  "meter_type": "pointer",
  "success": "yes",
  "result_summary": {
    "resultKind": "water_meter",
    "primaryLabel": "Final Reading",
    "primaryValue": "123.45",
    "secondaryLabel": "Meter Type",
    "secondaryValue": "pointer",
    "summaryText": "Water meter recognition finished."
  },
  "error_message": "",
  "created_at": "2026-06-01T06:16:10Z"
}

GET/api/open/tasks

Leggi le attività recenti di proprietà dell'attuale utente chiave API.

Esempio di richiesta
curl -X GET "https://watermeterai.com/api/open/tasks?limit=20" \
  -H "Authorization: Bearer wm_xxxxxxxxxxxxxxxxx"
Esempio di risposta
{
  "ok": true,
  "items": [
    {
      "task_id": "8e6c4d1f8f8348c0bc53e2e39d2dc111",
      "status": "done",
      "result_source": "cached_exact",
      "final_reading": "123.45",
      "meter_type": "pointer",
      "success": "yes",
      "result_summary": {},
      "ai_online": true,
      "is_latest_ai_version": true,
      "created_at": "2026-06-01T06:16:10Z",
      "error_message": ""
    }
  ]
}

POST/api/open/batches

Carica più immagini in un'unica richiesta.

Esempio di richiesta
curl -X POST "https://watermeterai.com/api/open/batches" \
  -H "Authorization: Bearer wm_xxxxxxxxxxxxxxxxx" \
  -F "files=@D:\data\meter_001.jpg" \
  -F "files=@D:\data\meter_002.jpg"
Esempio di risposta
{
  "ok": true,
  "batch_id": "5a14f4e5f6d34fdabce00e62c0dd0001",
  "status": "batch_running",
  "total_count": 2,
  "done_count": 0,
  "failed_count": 0,
  "pending_count": 2,
  "items": [
    {
      "index": 0,
      "file_name": "meter_001.jpg",
      "task_id": "task_a",
      "status": "queued",
      "result_source": "pending",
      "final_reading": "-",
      "failure_kind": "",
      "error_message": ""
    },
    {
      "index": 1,
      "file_name": "meter_002.jpg",
      "task_id": "task_b",
      "status": "queued",
      "result_source": "pending",
      "final_reading": "-",
      "failure_kind": "",
      "error_message": ""
    }
  ]
}

GET/api/open/batches/{batch_id}

Leggi l'avanzamento del batch e gli stati delle attività per file.

Esempio di richiesta
curl -X GET "https://watermeterai.com/api/open/batches/5a14f4e5f6d34fdabce00e62c0dd0001" \
  -H "Authorization: Bearer wm_xxxxxxxxxxxxxxxxx"
Esempio di risposta
{
  "ok": true,
  "batch_id": "5a14f4e5f6d34fdabce00e62c0dd0001",
  "status": "batch_done",
  "total_count": 2,
  "done_count": 2,
  "failed_count": 0,
  "pending_count": 0,
  "items": [
    {
      "index": 0,
      "file_name": "meter_001.jpg",
      "task_id": "task_a",
      "status": "done",
      "result_source": "fresh",
      "final_reading": "123.45",
      "failure_kind": "",
      "error_message": ""
    },
    {
      "index": 1,
      "file_name": "meter_002.jpg",
      "task_id": "task_b",
      "status": "done",
      "result_source": "cached_exact",
      "final_reading": "456.78",
      "failure_kind": "",
      "error_message": ""
    }
  ]
}

Flusso consigliato

  • Controlla `GET /api/open/ai-status` prima di inviare carichi elevati.
  • Salva `task_id` o `batch_id` nel tuo sistema subito dopo l'invio.
  • Considera `queued`, `running`, `waiting_ai`, `batch_waiting_ai` e `batch_running` come stati non finali e continua il polling.
  • Usa richieste batch quando il percorso di rete verso il backend ha latenza elevata e il business distribuito supporta la modalità batch.
  • Le richieste batch attualmente passano da `webBackend -> dispatchCenter -> waterMeterAi`.
  • `batch_waiting_ai` significa che ogni elemento è ancora in attesa del servizio IA, non è ancora in esecuzione attiva.
  • Quando il business distribuito è `CAD`, usa per ora `POST /api/open/tasks` e considera non disponibile il caricamento batch.

Note sugli errori

  • 400: richiesta non valida oppure l'azienda distribuita non supporta il caricamento batch.
  • 401: chiave API mancante, non valida, scaduta o disabilitata.
  • 403: the user account is not active, the key lacks the required scope, or the source IP is outside the key allowlist.
  • 404: attività o batch non trovato o non di proprietà dell'utente corrente.
  • 413: file troppo grande.
  • 415: tipo di immagine non supportato o contenuto di immagine non valido.
  • 429: quota exhausted or the API key request, submission, or concurrency limit was exceeded.
400 caricamento batch non disponibile
{
  "detail": "batch upload is not supported for business: cax"
}
401 Chiave API mancante o non valida
{
  "ok": false,
  "error": "unauthorized",
  "message": "Missing or invalid API key."
}
413 file troppo grande
{
  "ok": false,
  "error": "file_too_large",
  "message": "Maximum file size is 20MB."
}
Quota 429 esaurita
{
  "ok": false,
  "error": "quota_exhausted",
  "message": "Quota exhausted.",
  "quota": {
    "remaining": 0,
    "quota_summary_text": "Free daily quota: 20/20 used today. Remaining: 0."
  }
}

Pronto a testare il flusso?

Usa il workspace web per la prima foto, poi passa alle chiavi API quando il formato del risultato è adatto al tuo sistema.