# API database di film per il tuo catalogo

> Usa amodb come fonte del tuo database di film. Film, persone, società, collezioni, parole chiave e generi condividono ID numerici, quindi le righe si collegano senza problemi. Parti con la paginazione di discover per finestre di date di uscita, aggiorna in base all'età e collega i tuoi ID con la ricerca per ID esterno. JSON TMDB v3.

## Costruire il tuo database di film da un'API

amodb è un'API indipendente che parla il protocollo TMDB v3. Film, persone, società, collezioni, parole chiave e generi hanno tutti ID numerici e si richiamano a vicenda, quindi puoi riempire delle tabelle SQL con essa e tenerle aggiornate. Inizializza le tabelle con la paginazione di discover, aggiornale in base all'età e collega i tuoi identificativi con `find`. amodb non ha un feed delle modifiche, quindi un aggiornamento è semplicemente una nuova lettura delle righe che tieni.

Cosa ottieni:

- Sei tipi di entità collegate con ID numerici stabili.
- La paginazione di discover per il primo caricamento: fino a 20 risultati per pagina, 500 pagine per query.
- Finestre di date di uscita su discover, per suddividere il primo caricamento e per elencare le nuove uscite.
- Ricerche per ID esterno per `imdb_id`, `tvdb_id`, `wikidata_id` e `kinopoisk_id`.

## Quali dati ottieni

Questo è il modello dei dati. Ogni riga è una tabella in una copia relazionale.

| Entità        | Si legge con                        | Chiave          | Collegamenti a                                                                                        |
| ------------- | ----------------------------------- | --------------- | ----------------------------------------------------------------------------------------------------- |
| Film          | `GET /3/movie/{movie_id}`           | `id`, `imdb_id` | `genres[].id`, `production_companies[].id`, `belongs_to_collection.id`                                |
| Persona       | `GET /3/person/{person_id}`         | `id`, `imdb_id` | I film tramite `/3/movie/{movie_id}/credits`                                                          |
| Società       | `GET /3/company/{company_id}`       | `id`            | I film tramite `with_companies` in discover. `parent_company` è sempre `null` e `description` è vuoto |
| Collezione    | `GET /3/collection/{collection_id}` | `id`            | `parts[]`, una lista di film                                                                          |
| Parola chiave | `GET /3/keyword/{keyword_id}`       | `id`            | I film tramite `/3/keyword/{keyword_id}/movies` o `with_keywords`                                     |
| Genere        | `GET /3/genre/movie/list`           | `id`            | `genres[].id` sui film                                                                                |

I collegamenti molti a molti richiedono tabelle di join: `movie_genre`, `movie_company`, `movie_keyword` e `movie_credit`. Usa `credit_id` da [crediti](https://amodb.dev/it/credits/) come chiave dell'ultima. Gli elenchi dei campi sono nelle pagine [film](https://amodb.dev/it/movies/), [persone](https://amodb.dev/it/people/) e [collezioni](https://amodb.dev/it/collections/).

## Parti in 3 passaggi

1. Confronta le tre frequenze di richieste nella pagina dei [prezzi](https://amodb.dev/it/pricing/). Una frequenza maggiore accorcia il primo caricamento, nient'altro cambia.
2. Crea una chiave nella dashboard del tuo account e tienila in una variabile d'ambiente.
3. Chiama `/3/discover/movie` per una finestra di un giorno di date di uscita, poi recupera ogni ID della lista.

## Esempio di richiesta

Lo script PHP elenca i film usciti ieri e oggi tramite discover e inserisce o aggiorna ogni scheda in una tabella SQLite. Attende 3 secondi tra le letture dei dettagli per restare sotto le 20 richieste al minuto, ritenta un 429 dopo `Retry-After`, ed elimina le righe il cui ID ora restituisce 404.

```bash
curl -s "https://api.amodb.dev/3/discover/movie?primary_release_date.gte=2026-10-17&primary_release_date.lte=2026-10-18&sort_by=primary_release_date.asc&page=1" \
  -H "Authorization: Bearer $AMODB_KEY"
```

```php
<?php
const BASE = 'https://api.amodb.dev/3';

function amodb(string $path, array $query = []): ?array
{
    $url = BASE . $path . '?' . http_build_query($query);
    for ($attempt = 0; $attempt < 3; $attempt++) {
        $retryAfter = 1;
        $ch = curl_init($url);
        curl_setopt_array($ch, [
            CURLOPT_RETURNTRANSFER => true,
            CURLOPT_TIMEOUT => 10,
            CURLOPT_HTTPHEADER => ['Authorization: Bearer ' . getenv('AMODB_KEY')],
            CURLOPT_HEADERFUNCTION => function ($handle, $line) use (&$retryAfter) {
                if (stripos($line, 'Retry-After:') === 0) {
                    $retryAfter = max(1, (int) trim(substr($line, 12)));
                }
                return strlen($line);
            },
        ]);
        $body = curl_exec($ch);
        $status = curl_getinfo($ch, CURLINFO_HTTP_CODE);
        curl_close($ch);
        if ($status === 429) {
            sleep($retryAfter);
            continue;
        }
        if ($status === 404) {
            return null;
        }
        if ($status !== 200) {
            throw new RuntimeException("amodb returned $status for $path");
        }
        return json_decode($body, true);
    }
    throw new RuntimeException("Still rate limited on $path");
}

$db = new PDO('sqlite:movies.sqlite');
$db->exec('CREATE TABLE IF NOT EXISTS movie (id INTEGER PRIMARY KEY, imdb_id TEXT, title TEXT, release_date TEXT, raw TEXT)');
$save = $db->prepare('INSERT OR REPLACE INTO movie (id, imdb_id, title, release_date, raw) VALUES (?, ?, ?, ?, ?)');
$drop = $db->prepare('DELETE FROM movie WHERE id = ?');

$from = date('Y-m-d', strtotime('-1 day'));
$to = date('Y-m-d');
$page = 1;
do {
    $list = amodb('/discover/movie', [
        'primary_release_date.gte' => $from,
        'primary_release_date.lte' => $to,
        'sort_by' => 'primary_release_date.asc',
        'page' => $page,
    ]);
    foreach ($list['results'] as $row) {
        $movie = amodb('/movie/' . $row['id'], ['language' => 'en-US']);
        if ($movie === null) {
            $drop->execute([$row['id']]);
            continue;
        }
        $save->execute([$movie['id'], $movie['imdb_id'] ?? null, $movie['title'], $movie['release_date'] ?? null, json_encode($movie)]);
        sleep(3);
    }
    $page++;
} while ($page <= min($list['total_pages'], 500));
```

Discover restituisce righe di lista, non schede complete. Questi sono 2 dei 20 risultati della pagina 1. Leggi `/3/movie/{id}` per gli altri campi.

```json
{
  "page": 1,
  "results": [
    {
      "adult": false,
      "backdrop_path": "/siepLRGVjM8yLKppApkD3uSh8Y0.jpg",
      "genre_ids": [
        35
      ],
      "id": 1800227,
      "original_language": "en",
      "original_title": "Sly's Pack",
      "overview": "Nesmith, Gary, & Tony are smoking weed on the roof of a parking garage, but a...",
      "popularity": 0.0071,
      "poster_path": "/3HpIWZUI7jmpKZkfZNdchS2WsvN.jpg",
      "release_date": "2026-10-17",
      "title": "Sly's Pack",
      "video": false,
      "vote_average": 0,
      "vote_count": 0
    },
    {
      "adult": false,
      "backdrop_path": null,
      "genre_ids": [
        99
      ],
      "id": 1800168,
      "original_language": "en",
      "original_title": "The Good Life",
      "overview": "The Good LIfe is based on the best-selling book by Drs. Robert Waldinger and...",
      "popularity": 0.0143,
      "poster_path": null,
      "release_date": "2026-10-17",
      "title": "The Good Life",
      "video": false,
      "vote_average": 0,
      "vote_count": 0
    }
  ],
  "total_pages": 15,
  "total_results": 299
}
```

## Riempire e aggiornare le tabelle

| Compito                  | Chiamata                                                                                                           | Limiti                                                                                                                                     |
| ------------------------ | ------------------------------------------------------------------------------------------------------------------ | ------------------------------------------------------------------------------------------------------------------------------------------ |
| Primo caricamento        | `GET /3/discover/movie` con `sort_by` e una finestra di date                                                       | `page` da 1 a 500, fino a 20 risultati per pagina, cioè 10.000 per query. Dividi con `primary_release_date.gte` e `.lte` per andare oltre. |
| Nuove uscite             | `GET /3/discover/movie` con `primary_release_date.gte` impostato sull'ultima esecuzione, e `GET /3/movie/upcoming` | In cache per 30 minuti.                                                                                                                    |
| Aggiornare le righe      | `GET /3/movie/{movie_id}` per le righe più vecchie di 6 ore                                                        | Non c'è un feed delle modifiche. Aggiorna i titoli che gli utenti aprono, e gli altri meno spesso.                                         |
| Collegare i tuoi ID      | `GET /3/find/{external_id}`                                                                                        | Un ID per chiamata, fonte scelta con `external_source`.                                                                                    |
| Riempimento su richiesta | `GET /3/movie/{movie_id}` quando un utente apre un titolo                                                          | Salva la risposta con un timestamp.                                                                                                        |

La finestra di paginazione è la scelta progettuale principale. Quando `total_pages` in una risposta supera 500, la finestra contiene più di 10.000 righe, quindi dividila a metà finché non rientra. Un anno recente richiede dei mesi, e un giorno di uscite sono poche centinaia di titoli. Salva la fetta completata così un'esecuzione interrotta può riprendere. Le regole di corrispondenza per il join sono nella pagina [ricerca per ID esterno](https://amodb.dev/it/find-by-external-id/).

## Dimensionare la sincronizzazione

Ogni riga che aggiorni costa una lettura di dettagli. Un piano da 20 richieste al minuto dà 1.200 chiamate all'ora, 40 ne dà 2.400 e 120 ne dà 7.200. Una pagina di discover elenca 20 ID con una chiamata. Esegui l'aggiornamento nelle ore di minore traffico se la tua app condivide la chiave, perché il limite è per chiave e non per script. Vedi [limiti di richieste](https://amodb.dev/it/rate-limits/) per gli header che indicano quanto resta nella finestra.

## Cache su due livelli

| Livello        | Contiene                            | TTL                                                                       |
| -------------- | ----------------------------------- | ------------------------------------------------------------------------- |
| Cache edge     | Dettagli e crediti                  | 6 ore                                                                     |
| Cache edge     | Liste discover, tendenze e popolari | 30 minuti                                                                 |
| Cache edge     | Ricerca                             | 10 minuti                                                                 |
| Cache edge     | Configurazione                      | 24 ore                                                                    |
| Cache edge     | Immagini                            | 30 giorni                                                                 |
| Le tue tabelle | Le righe che tieni                  | Finché la tua regola sull'età non impone di rileggere, mai prima di 6 ore |

La cache edge è condivisa tra le chiavi, ma il limite di richieste viene prima, quindi una risposta dalla cache usa comunque una richiesta del tuo minuto. Rileggere una riga più spesso che ogni 6 ore restituisce la stessa copia e spreca quota. Lascia che sia una regola sull'età a decidere quando rileggere.

## Confronto

| Funzionalità               | Fare scraping delle pagine da solo    | File di dataset statici                | amodb                                                                |
| -------------------------- | ------------------------------------- | -------------------------------------- | -------------------------------------------------------------------- |
| Freschezza                 | Fresco quanto la tua ultima scansione | Fresco quanto l'ultimo file pubblicato | Dettagli in cache 6 ore, rilettura in base all'età                   |
| Aggiornamenti incrementali | Rifare la scansione e confrontare     | Scaricare un nuovo file                | Discover con finestra di date di uscita, nessun feed delle modifiche |
| ID tra entità              | URL delle pagine                      | Definiti dall'editore                  | ID numerici, `imdb_id` e `/3/find`                                   |
| Cosa gestisci              | Crawler e storage                     | Storage e un job di importazione       | Storage e uno script di sincronizzazione                             |
| Limite di richieste        | Stabilito dai siti che scansioni      | Non applicabile                        | 20, 40 o 120 richieste al minuto, contate per chiave                 |
| Lingue per scheda          | Quelle offerte da ogni pagina         | Dipende dai file                       | 14, scelte con `language`                                            |

## Prezzi

Il primo caricamento è la parte costosa, ed è limitato dalle tue richieste al minuto. Scegli 20, 40 o 120 al minuto nella pagina dei [prezzi](https://amodb.dev/it/pricing/). Paga 1, 3, 6, 12 o 24 mesi con uno sconto di 0, 10, 20, 30 o 40 per cento. Nulla si rinnova automaticamente, non esiste un piano gratuito, e ogni piano legge gli stessi dati.

## Domande e risposte

### Come mantengo aggiornata una copia locale?

amodb non ha un feed delle modifiche, quindi aggiorna in base all'età. I dettagli restano in cache sull'edge per 6 ore, quindi non rileggere una riga prima. Recupera le nuove uscite con discover e primary_release_date.gte impostato sull'ultima esecuzione.

### Come carico la prima copia?

Scorri /3/discover/movie con page da 1 a 500 (fino a 20 risultati ciascuna, cioè 10.000 per query) e dividi per finestre primary_release_date per andare oltre. Il solo marzo 2025 contiene circa 4.400 titoli. Poi leggi /3/movie/{id} per ogni ID che tieni.

### Quanto dura un primo caricamento con il mio limite di richieste?

A 20 richieste al minuto puoi fare 1.200 chiamate all'ora, a 40 sono 2.400 e a 120 sono 7.200. Dividi il numero di letture di dettagli che ti servono per quella cifra per pianificare l'esecuzione.

### Posso collegare gli ID amodb a quelli che già salvo?

Sì. /3/find/{external_id} accetta imdb_id, tvdb_id, wikidata_id e kinopoisk_id e restituisce la scheda amodb corrispondente. Anche le schede dei film portano imdb_id, quindi il join funziona in entrambe le direzioni.

### C'è un piano gratuito per costruire un database?

No. L'accesso è prepagato per 1, 3, 6, 12 o 24 mesi e non si rinnova da solo. Ogni piano legge gli stessi dati, quindi un piano più grande rende solo più veloci il primo caricamento e gli aggiornamenti.

## Pagine correlate

- [API dei dettagli del film](https://amodb.dev/it/movies/): API dettagli film con gli stessi percorsi e JSON di TMDB v3. Ottieni un film per ID, aggiungi crediti, valutazioni e mood con append_to_response, in 14 lingue.
- [API dei dettagli della persona](https://amodb.dev/it/people/): API dettagli persona con gli stessi percorsi e JSON di TMDB v3. Ottieni attore o troupe per ID, con biografia, filmografia, ID esterni e lista dei popolari.
- [API delle collezioni](https://amodb.dev/it/collections/): API collezioni di film con percorsi TMDB v3: recupera una saga per ID con tutte le sue parti, leggi belongs_to_collection su un film e cerca per nome.
- [Società ed emittenti](https://amodb.dev/it/companies-networks/): Cerca case di produzione ed emittenti TV con i percorsi TMDB v3. Leggi nome, paese e logo per ID, poi filtra discover per ID di società o emittente.
- [Ricerca per ID esterno](https://amodb.dev/it/find-by-external-id/): Cerca un film, una serie o una persona per ID IMDb, TVDB, Wikidata o Kinopoisk con l'endpoint find di TMDB, e leggi ID esterni e dati Wikidata di un titolo.
- [Limiti di richieste](https://amodb.dev/it/rate-limits/): amodb limita ogni chiave per richieste al minuto in una finestra scorrevole di 60 secondi: 20, 40 o 120 in base al piano. Leggi gli header, gestisci il 429.

Aggiornato: 2026-10-18. Source: https://amodb.dev/it/movie-database-api/
