Skip to content

Market Scanner integration โ€‹

Integrate with an AI assistant
Download or copy the integration prompt for Market Scanner and paste it into Claude Code, Cursor or Copilot: it contains auth, end-to-end examples and a checklist.
Open

Dokicasa's Scanner APIs let you obtain deeds (visure), inspections, notes, cadastral maps and address searches. They are asynchronous: this guide shows how to receive results efficiently, avoiding polling when possible.

Base URLhttps://api.dokicasa.it
AuthAuthorization: Bearer <api_token>
Content-Typeapplication/json

Documentation and authentication โ€‹

Interactive docs for all endpoints are on Swagger: api.dokicasa.it/api-doc/ โ†’ Scanner section.

Every call must be authenticated with a Bearer token:

http
Authorization: Bearer YOUR_API_TOKEN

WARNING

The token must never end up in public repos or the frontend: treat it like a password.

Main endpoints โ€‹

Summary table โ€” the full schema is on Swagger.

MethodPathWhat it does
POST/api/scanner/{type}Create a scanner request (visura / inspection / map / list-addresses / โ€ฆ). Returns scanner_request_id.
GET/api/scanner-request/{id}Request status + final result (for PDFs and list-addresses the payload is already here).
GET/api/scanner-request/{id}/resultsStructured results for "normal" searches (e.g. properties from an address).
WSprivate-scanner_request.{id}Private WebSocket channel for realtime updates.

Request states โ€‹

ENQUEUED  โ†’  SCANNING  โ†’  SUCCESS
                       โ•ฒโ†’  ERROR

ENQUEUED and SCANNING are transient; SUCCESS and ERROR are final.

How it works โ€‹

All scanner calls are asynchronous. The flow is always the same, only how you receive the status update changes.

  1. Create the request โ€” POST /api/scanner/{type} โ†’ you get a scanner_request_id and the initial state ENQUEUED.
  2. Wait for completion โ€” pick one of these (in order of preference):
    • WebSocket โ€” instant push, no polling.
    • Webhook callback โ€” our server calls yours when it finishes.
    • Polling (fallback) โ€” only if you can't use the two above.
  3. Get the result โ€” when the state is SUCCESS:
    • PDF (visure, inspections, maps, notes): the file is already in the GET /api/scanner-request/{id} response.
    • Structured searches: call GET /api/scanner-request/{id}/results.

Realtime updates via WebSocket โ€‹

โญ Recommended for frontend apps

Recommended approach for web/mobile: no polling, instant updates, progress bars and push notifications.

Each request publishes events on a dedicated private channel:

private-scanner_request.{id}

where {id} is the scanner_request_id returned by the initial POST.

Full example (JavaScript + Pusher/Reverb) โ€‹

js
import Pusher from 'pusher-js'

const apiToken = 'YOUR_API_TOKEN'

const pusher = new Pusher('ra9jcihuz0sx7vtw8yut', {
  wsHost: 'socket.dokicasa.it',
  wsPort: 443,
  wssPort: 443,
  forceTLS: false,
  cluster: 'mt1',
  disableStats: true,
  enabledTransports: ['ws', 'wss'],
  authEndpoint: 'https://api.dokicasa.it/broadcasting/auth',
  auth: { headers: { Authorization: 'Bearer ' + apiToken } },
})

const { scanner_request_id } = await fetch(
  'https://api.dokicasa.it/api/scanner/intestatari-catasto',
  {
    method: 'POST',
    headers: {
      Authorization: 'Bearer ' + apiToken,
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      comune: 'H501', provincia: 'RM',
      foglio: '123', particella: '45',
      search_catasto_type: 'F',
    }),
  }
).then((r) => r.json())

const channel = pusher.subscribe(`private-scanner_request.${scanner_request_id}`)
channel.bind('ScannerRequestNotification', ({ message }) => {
  const { status, percentage } = message
  if (status === 'SCANNING') updateProgressBar(percentage)
  if (status === 'SUCCESS') fetchResult(scanner_request_id)
  if (status === 'ERROR') handleError(message)
})

async function fetchResult(id) {
  const data = await fetch(`https://api.dokicasa.it/api/scanner-request/${id}`, {
    headers: { Authorization: 'Bearer ' + apiToken },
  }).then((r) => r.json())
  console.log('Final result:', data)
}

Webhook callback (server-to-server) โ€‹

โญ Recommended for backend integrations

Pass a URL when creating the request: when it finishes, Dokicasa POSTs the result to you.

Add the callback field to the initial POST body:

json
{
  "comune": "H501",
  "foglio": "123",
  "particella": "45",
  "callback": "https://your-server.com/dokicasa/scanner-done"
}

What your endpoint receives โ€‹

When processing finishes (state SUCCESS or ERROR), our server POSTs to the URL with:

  • the request id;
  • the final status (SUCCESS / ERROR);
  • the result data (owners, properties, processed PDF, metadata, โ€ฆ) when available.

NOTE

The webhook is already live in production: if callback is set, the call fires automatically when processing ends โ€” no setup in the panel.

Idempotency

The system may re-send the webhook on network errors. Identify the request by its id in the body and always respond 2xx, even on duplicates, to avoid useless retries.

You have an address and want the associated cadastral properties. Two phases: address resolution โ†’ properties.

  1. list-addresses (address resolution) โ€” POST /api/scanner/list-addresses. Wait via socket/webhook/polling. The normalized address list is already in the results field of GET /api/scanner-request/{id} โ€” no need to call /results.
  2. Properties from an address โ€” use an address from step 1 as address_value in the properties scanner call (exact endpoint on Swagger, Scanner section).
  3. Fetch results โ€” when SUCCESS arrives, call GET /api/scanner-request/{id}/results for the property list.

Use case: visure, inspections, notes, maps (PDF) โ€‹

All requests producing a PDF (cadastral visura, inspection, note, map) follow the same pattern.

  1. Create the request โ€” POST /api/scanner/{type} (type depends on the document, see Swagger).
  2. Wait for completion โ€” via WebSocket or webhook: state goes ENQUEUED โ†’ SCANNING up to SUCCESS or ERROR.
  3. Automatic retry on transient errors โ€” if a temporary error occurs (line issues with external services), the system retries by itself every ~5 minutes. You don't need to resend anything. Credit is charged only on the first success.
  4. Get the PDF โ€” the file is returned directly in the GET /api/scanner-request/{id} response (no /results). The PDF is also sent automatically by email to the address bound to the token, so the end user gets it even without integrating the client-side download.

Polling โ€” last resort only โ€‹

Not recommended

You have two push mechanisms (WebSocket and webhook) that remove the need for polling. Consider them first: polling increases latency and server load with no real benefit.

If you really must poll, query periodically:

http
GET /api/scanner-request/{id}

Practical guidelines:

  • Recommended minimum interval: 3 seconds between calls.
  • Exponential backoff after a few attempts (e.g. 3s โ†’ 6s โ†’ 12s).
  • A sensible attempt limit (e.g. 5 minutes total), then time out on your side.
  • Stop as soon as the state is SUCCESS or ERROR.

Typical response:

json
{ "id": 12345, "status": "SCANNING", "percentage": 42 }

Operational notes โ€‹

  • Always keep the id (scanner_request_id) returned at creation: you need it for every later operation.
  • Handle the ERROR state explicitly: read the message to understand the cause.
  • Never share the API token: treat it like a password.
  • In production, prefer webhook or socket over polling.