Reserveserveren er en annen adresse som kjører nøyaktig det samme API-et. Den er der for tilfeller der en forespørsel til `portal.bulkgate.com` ikke kommer frem i det hele tatt — reserveverten tar imot forespørselen og sender den videre en annen vei.

## Hvordan tjenesten er bygd opp

BulkGate kjører på flere servere på **tre geografiske steder**. Hvis én av dem faller ut, tar de øvrige automatisk over trafikken — ingenting endres for integrasjonen din, og `portal.bulkgate.com` fortsetter å svare. Det tilfellet trenger du ikke å håndtere selv. Hele oppsettet er beskrevet i [Infrastruktur](https://www.bulkgate.com/no/hjelpesenter/generell-informasjon/api-infrastruktur/).

Det dette ikke dekker, er **veien til oss**. Et brudd på strekningen mellom serveren din og vår — hos en operatør, hos en leverandør av nettilkobling eller hvor som helst imellom — ligger utenfor vår kontroll, og forespørselen når oss da aldri. Det er det reserveverten er til for.

Gjeldende tjenestestatus finner du på [bulkgate.status.online](https://bulkgate.status.online/en/).

## Adresse

```url
https://backup1.bulkgate.com
```

Verten er en en-til-en-erstatning — stier, parametere, tilgangsopplysninger og svar er identiske med `portal.bulkgate.com`. Det eneste du bytter, er domenet:

```url
https://portal.bulkgate.com/api/2.0/advanced/transactional
https://backup1.bulkgate.com/api/2.0/advanced/transactional
```

Den fungerer med samme konto, samme [token](https://www.bulkgate.com/no/dokumentasjon/api-administrasjon/api-token/) og samme kreditt. Det er ingenting å sette opp og ingenting å slå på.

> [!CAUTION]
> **Ikke bruk reserveverten som primæradresse.** Den kan tas ned for vedlikehold når som helst og uten varsel — den skal bare bære trafikk mens hovedverten er utilgjengelig. Ha `portal.bulkgate.com` først i rekkefølgen.

## Når du skal bytte til den

> [!IMPORTANT]
> Reserveverten løser et **tilkoblingsbrudd, ikke en avvist forespørsel**. En forespørsel som API-et har avvist, besvarer den på nøyaktig samme måte.

Bytt når forespørselen **ikke får noe svar**:

| situasjon | bytte? |
|:--------------------------------------------------------------|:-----------|
| Tidsavbrudd ved tilkobling eller lesing                       | **Ja**     |
| DNS kunne ikke slås opp                                       | **Ja**     |
| Tilkoblingen ble avvist, nettverket er utilgjengelig          | **Ja**     |
| HTTP 5xx uten innhold                                         | **Ja**     |
| Et svar med en [feiltype](https://www.bulkgate.com/no/dokumentasjon/api-administrasjon/api-feiltyper/) (4xx)     | Nei        |
| `429 Too Many Requests` ([grenser](https://www.bulkgate.com/no/dokumentasjon/api-administrasjon/api-foresporselsgrenser/)) | Nei     |

I de to siste tilfellene svarte API-et — forespørselen kom frem og ble behandlet. Gjentar du den på reserveverten, får du samme feil og bruker bare opp enda et forsøk fra grensen din.

## Bygge reserveløsningen inn i integrasjonen

Ha adressene i en ordnet liste og prøv dem etter tur. Mislykkes tilkoblingen, går du videre til neste; har API-et svart, returnerer du resultatet som det er.

```php
$hosts = ['portal.bulkgate.com', 'backup1.bulkgate.com'];

foreach ($hosts as $host)
{
    $curl = curl_init();

    curl_setopt_array($curl, [
        CURLOPT_URL => "https://$host/api/2.0/advanced/transactional",
        CURLOPT_POST => true,
        CURLOPT_RETURNTRANSFER => true,
        CURLOPT_TIMEOUT => 30,
        CURLOPT_HTTPHEADER => ['Content-Type: application/json'],
        CURLOPT_POSTFIELDS => json_encode([
            'application_id' => 451,
            'application_token' => 'NKN02TWE6NfBkfl-your-secret-token-Wf05GaqLIWLW4aBj',
            'number' => ['420777777777'],
            'text' => 'Your order 4517 has been shipped.',
            // Sikring mot dobbel sending når første forsøk fikk tidsavbrudd,
            // men meldingen likevel gikk ut — se Hva du bør passe på.
            'duplicates_check' => 'on',
        ], JSON_THROW_ON_ERROR),
    ]);

    $body = curl_exec($curl);
    $error = curl_error($curl);

    curl_close($curl);

    // Tilkoblingen mislyktes — prøv neste adresse.
    if ($body === false)
    {
        continue;
    }

    // API-et svarte, enten med suksess eller med feil. Ikke bytt videre.
    print_r(json_decode($body, true, flags: JSON_THROW_ON_ERROR));

    break;
}
```

```python
# pip install requests
import requests

hosts = ['portal.bulkgate.com', 'backup1.bulkgate.com']

for host in hosts:
    try:
        response = requests.post(f'https://{host}/api/2.0/advanced/transactional', json={
            'application_id': 451,
            'application_token': 'NKN02TWE6NfBkfl-your-secret-token-Wf05GaqLIWLW4aBj',
            'number': ['420777777777'],
            'text': 'Your order 4517 has been shipped.',
            'duplicates_check': 'on',
        }, timeout=30)
    except requests.RequestException:
        continue   # tilkoblingen mislyktes, prøv neste adresse

    print(response.json())
    break
```

```js
const hosts = ['portal.bulkgate.com', 'backup1.bulkgate.com'];

for (const host of hosts) {
  let response;

  try {
    response = await fetch(`https://${host}/api/2.0/advanced/transactional`, {
      method: 'POST',
      headers: {'Content-Type': 'application/json'},
      body: JSON.stringify({
        application_id: 451,
        application_token: 'NKN02TWE6NfBkfl-your-secret-token-Wf05GaqLIWLW4aBj',
        number: ['420777777777'],
        text: 'Your order 4517 has been shipped.',
        duplicates_check: 'on',
      }),
    });
  } catch {
    continue;   // tilkoblingen mislyktes, prøv neste adresse
  }

  console.log(await response.json());
  break;
}
```

## Hva du bør passe på

> [!WARNING]
> Et tidsavbrudd betyr ikke at meldingen ikke ble sendt. Forespørselen kan ha kommet frem, mens svaret gikk tapt på vei tilbake — et nytt forsøk på reserveverten ville da sende meldingen en gang til.

Derfor bør du sende `duplicates_check` slått på for **transaksjonsendepunktene**. En melding med samme tekst til samme nummer forkastes innenfor et vindu på **5 minutter**, så det gjentatte forsøket dupliserer ingenting.

> [!IMPORTANT]
> På **markedsføringsendepunktene** beskytter ikke `duplicates_check` et nytt forsøk — den fjerner bare duplikater innenfor én og samme sending, ikke på tvers av forespørsler. En gjentatt forespørsel er en ny sending for den og går ut i sin helhet. Ved massesendinger bør du heller sjekke om det første forsøket gikk gjennom før du gjentar det.

Angi et fornuftig tidsavbrudd. Uten det venter klienten på et svar som aldri kommer, og når aldri frem til reserveverten.

> [!NOTE]
> **Idempotens i API-et** er under utvikling — en gjentatt forespørsel skal kunne merkes slik at API-et gjenkjenner den og returnerer resultatet av den opprinnelige i stedet for å sende på nytt. Da forsvinner forskjellen mellom transaksjons- og markedsføringsendepunkter som er beskrevet over. Vi dokumenterer fremgangsmåten her så snart den er tilgjengelig.
