# Bestellpreis berechnen

`POST /account/api/v1/quote`

## Autorisierung

`Authorization: Bearer YOUR_ARNPROXY_API_KEY`

`Accept: application/json`

Erforderliche Berechtigung: `read`

`Content-Type: application/json`

## Parameter

| Name | Typ | Erforderlich / Bedingt | Standardwert | Beschreibung |
|---|---|---|---|---|
| `product_id` (body) | integer | Erforderlich | — | Produkt-ID aus products; 1–2147483647. |
| `lines` (body) | object[] | Erforderlich | — | 1–20 verschiedene Standortzeilen für ein Produkt. location_id nicht doppeln; insgesamt höchstens 100000 Proxys. |
| `lines[].location_id` (body) | integer | Erforderlich | — | Standort-ID aus dem gewählten Produktkatalog. |
| `lines[].time_id` (body) | integer | Erforderlich | — | Für diesen Standort angebotene Laufzeit-ID. |
| `lines[].quantity` (body) | integer | Erforderlich | — | 1–100000; zusätzlich gilt product.minimum_quantity. |
| `promo_code` (body) | string | Optional | `""` | Optionaler Aktionscode, höchstens 100 Bytes. Zwischen Preisabfrage und Kauf/Verlängerung unverändert lassen. |

## Anfrageinhalt

Ersetzen Sie YOUR_/FROM_ durch Werte aus Katalog, Angebot oder Umfang. Beispiele lassen die Zustimmung auf false; bestätigen Sie echte Vorgänge nur bewusst.

```json
{
  "product_id": "FROM_PRODUCTS",
  "lines": [
    {
      "location_id": "FROM_CATALOG",
      "time_id": "FROM_CATALOG",
      "quantity": 1
    }
  ],
  "promo_code": ""
}
```

## Weitere Anwendungsbeispiele

IDs und Preise sind beispielhaft; verwenden Sie echte Werte aus dem Katalog und demselben Angebot. JSON-IDs und expected_total_minor müssen Zahlen sein. Beispiele verwenden bewusst terms=false. Senden Sie terms=true nur nach ausdrücklicher Zustimmung zur kostenpflichtigen Aktion.

### Ein Produkttyp, zwei Länder

Für quote enthalten die Positionen keinen Verwendungszweck: location_id, time_id und quantity reichen aus. Die Zweckfelder sind bei purchase erforderlich.

```json
{
  "product_id": 5,
  "lines": [
    {
      "location_id": 10,
      "time_id": 101,
      "quantity": 1
    },
    {
      "location_id": 11,
      "time_id": 102,
      "quantity": 1
    }
  ],
  "promo_code": ""
}
```

## Anfragebeispiel

### curl

```curl
printf 'Authorization: Bearer %s\n' "$ARNPROXY_API_KEY" |
  curl --silent --show-error --header @- \
    --header 'Accept: application/json' \
    --connect-timeout 10 --max-time 30 \
    --request POST --header 'Content-Type: application/json' \
    --data-binary @request.json \
    'https://www.arnproxy.com/account/api/v1/quote'
```

### python

```python
import os, requests

headers = {"Authorization": "Bearer " + os.environ["ARNPROXY_API_KEY"]}
import json
with open("request.json", encoding="utf-8") as f:
    payload = json.load(f)
response = requests.post(
    "https://www.arnproxy.com/account/api/v1/quote",
    headers=headers, json=payload,
    timeout=(10, 30), allow_redirects=False
)
print(response.status_code, response.text)
# No automatic write retry.
```

### javascript

```javascript
const headers = { Authorization: `Bearer ${process.env.ARNPROXY_API_KEY}` };
const { readFile } = await import('node:fs/promises');
headers['Content-Type'] = 'application/json';
const body = await readFile('request.json', 'utf8');
const response = await fetch("https://www.arnproxy.com/account/api/v1/quote", {
  method: 'POST', headers, redirect: 'error',
  signal: AbortSignal.timeout(30000), body
});
console.log(response.status, await response.text());
// A write timeout is ambiguous; query its saved operation.
```

### php

```php
<?php
$headers = ['Accept: application/json',
    'Authorization: Bearer '.getenv('ARNPROXY_API_KEY')];
$headers[] = 'Content-Type: application/json';
$ch = curl_init('https://www.arnproxy.com/account/api/v1/quote');
curl_setopt_array($ch, [
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER => $headers,
    CURLOPT_FOLLOWLOCATION => false,
    CURLOPT_SSL_VERIFYPEER => true, CURLOPT_SSL_VERIFYHOST => 2,
    CURLOPT_CONNECTTIMEOUT => 10, CURLOPT_TIMEOUT => 30,
    CURLOPT_POST => true,
    CURLOPT_POSTFIELDS => file_get_contents('request.json'),
]);
$result = curl_exec($ch);
if ($result === false) {
    // Do not repeat a write; use the original operation key.
    throw new RuntimeException('Transport result unknown');
}
echo curl_getinfo($ch, CURLINFO_HTTP_CODE).PHP_EOL.$result;
curl_close($ch);
```

### go

```go
package main

import (
  "fmt"
  "io"
  "net/http"
  "os"
  "time"
)

func main() {
  client := &http.Client{Timeout: 30*time.Second,
    CheckRedirect: func(req *http.Request, via []*http.Request) error {
      return http.ErrUseLastResponse
    }}
  var body io.Reader
  file, err := os.Open("request.json"); if err != nil { panic(err) }
  defer file.Close(); body = file
  req, err := http.NewRequest("POST", "https://www.arnproxy.com/account/api/v1/quote", body)
  if err != nil { panic(err) }
  req.Header.Set("Authorization", "Bearer "+os.Getenv("ARNPROXY_API_KEY"))
  req.Header.Set("Content-Type", "application/json")
  res, err := client.Do(req); if err != nil { panic(err) }
  defer res.Body.Close()
  data, err := io.ReadAll(res.Body); if err != nil { panic(err) }
  fmt.Println(res.StatusCode, string(data))
}
```

### csharp

```csharp
using System;
using System.IO;
using System.Net.Http;
using System.Net.Http.Headers;
using System.Text;

using var handler = new HttpClientHandler { AllowAutoRedirect = false };
using var client = new HttpClient(handler) { Timeout = TimeSpan.FromSeconds(30) };
using var request = new HttpRequestMessage(HttpMethod.Post,
    "https://www.arnproxy.com/account/api/v1/quote");
request.Headers.Authorization = new AuthenticationHeaderValue(
    "Bearer", Environment.GetEnvironmentVariable("ARNPROXY_API_KEY"));
request.Content = new StringContent(
    await File.ReadAllTextAsync("request.json"), Encoding.UTF8, "application/json");
using var response = await client.SendAsync(request);
Console.WriteLine((int)response.StatusCode);
Console.WriteLine(await response.Content.ReadAsStringAsync());
// Never automatically retry an ambiguous write.
```

### java

```java
import java.net.URI;
import java.net.http.*;
import java.nio.charset.StandardCharsets;
import java.nio.file.*;

// Inside your application method:
var client = HttpClient.newHttpClient();
var request = HttpRequest.newBuilder(URI.create("https://www.arnproxy.com/account/api/v1/quote"))
    .header("Authorization", "Bearer " + System.getenv("ARNPROXY_API_KEY"))
    .header("Accept", "application/json")
    .header("Content-Type", "application/json")
    .POST(HttpRequest.BodyPublishers.ofString(
        Files.readString(Path.of("request.json"), StandardCharsets.UTF_8)))
    .build();
var response = client.send(request, HttpResponse.BodyHandlers.ofString());
System.out.println(response.statusCode());
```

## Antworten · HTTP 200

```json
{
  "ok": true,
  "data": {
    "product": {
      "id": 5,
      "name": "IPv4 Proxy",
      "minimum_quantity": 1
    },
    "currency": "TRY",
    "quantity": 1,
    "base_total": "10.00",
    "quantity_discount_amount": "0.00",
    "subtotal": "10.00",
    "promotion": {
      "code": "",
      "rate": "0.00",
      "amount": "0.00"
    },
    "total": "10.00",
    "total_minor": 1000,
    "lines": [
      {
        "location_id": 10,
        "country": "Example country",
        "time_id": 101,
        "period": "7 days",
        "days": 7,
        "quantity": 1,
        "base_unit_price": "10.0000",
        "quantity_discount_rate": "0.00",
        "unit_price": "10.0000",
        "base_total": "10.00",
        "subtotal": "10.00",
        "promotion_amount": "0.00",
        "total": "10.00",
        "total_minor": 1000
      }
    ],
    "discount_scope": "country",
    "estimate_only": true,
    "stock_checked": false,
    "purchase_available": false,
    "calculated_at": "2030-01-01T12:00:00+00:00"
  },
  "meta": {
    "request_id": "000000000000000000000001",
    "phase": "public_v1",
    "source": "arnproxy_records"
  }
}
```

| Name | Typ | Bedingt | Beschreibung |
|---|---|---|---|
| `ok` | boolean | — | Erfolgskennzeichen; bei false error.code prüfen. |
| `data` | object | — | Vorgangsspezifisches Ergebnis; Beispiele sind synthetisch und dienen der Veranschaulichung. |
| `data.product` | object | — | Vorgangsspezifischer Wert für product. Rückgabetyp beibehalten und Verhaltenshinweise beachten. |
| `data.product.id` | integer | — | Zugehörige ARNPROXY-Datensatz-ID statt interner Anbieter-ID verwenden. |
| `data.product.name` | string | — | Vorgangsspezifischer Wert für name. Rückgabetyp beibehalten und Verhaltenshinweise beachten. |
| `data.product.minimum_quantity` | integer | — | Mindestmenge je Bestellzeile dieses Produkts. |
| `data.currency` | string | — | Kontowährung der Transaktion: TRY oder USD. |
| `data.quantity` | integer | — | Gewählte oder bestellte Proxyanzahl. |
| `data.base_total` | string | — | Geldbetrag; Text-/Ganzzahldarstellung für Genauigkeit beibehalten. |
| `data.quantity_discount_amount` | string | — | Vorgangsspezifischer Wert für quantity discount amount. Rückgabetyp beibehalten und Verhaltenshinweise beachten. |
| `data.subtotal` | string | — | Geldbetrag; Text-/Ganzzahldarstellung für Genauigkeit beibehalten. |
| `data.promotion` | object | — | Vorgangsspezifischer Wert für promotion. Rückgabetyp beibehalten und Verhaltenshinweise beachten. |
| `data.promotion.code` | string | — | Vorgangsspezifischer Wert für code. Rückgabetyp beibehalten und Verhaltenshinweise beachten. |
| `data.promotion.rate` | string | — | Vorgangsspezifischer Wert für rate. Rückgabetyp beibehalten und Verhaltenshinweise beachten. |
| `data.promotion.amount` | string | — | Geldbetrag; Text-/Ganzzahldarstellung für Genauigkeit beibehalten. |
| `data.total` | string | — | Geldbetrag; Text-/Ganzzahldarstellung für Genauigkeit beibehalten. |
| `data.total_minor` | integer | — | Ganzzahl in kleinster Währungseinheit: 1000 bedeutet 10.00 TRY/USD. |
| `data.lines` | array | — | Vorgangsspezifischer Wert für lines. Rückgabetyp beibehalten und Verhaltenshinweise beachten. |
| `data.lines[]` | object | — | Vorgangsspezifischer Wert für lines. Rückgabetyp beibehalten und Verhaltenshinweise beachten. |
| `data.lines[].location_id` | integer | — | Lokale Katalog-ID für Standort oder Produkttyp. |
| `data.lines[].country` | string | — | Vorgangsspezifischer Wert für country. Rückgabetyp beibehalten und Verhaltenshinweise beachten. |
| `data.lines[].time_id` | integer | — | Lokale Laufzeit-/GB-Plan-ID, keine Anzahl von Tagen oder GB. |
| `data.lines[].period` | string | — | Lesbare Laufzeitbezeichnung aus dem Katalog. |
| `data.lines[].days` | integer | — | Laufzeit in Tagen, getrennt vom Trafficvolumen des GB-Plans. |
| `data.lines[].quantity` | integer | — | Gewählte oder bestellte Proxyanzahl. |
| `data.lines[].base_unit_price` | string | — | Vorgangsspezifischer Wert für base unit price. Rückgabetyp beibehalten und Verhaltenshinweise beachten. |
| `data.lines[].quantity_discount_rate` | string | — | Vorgangsspezifischer Wert für quantity discount rate. Rückgabetyp beibehalten und Verhaltenshinweise beachten. |
| `data.lines[].unit_price` | string | — | Vorgangsspezifischer Wert für unit price. Rückgabetyp beibehalten und Verhaltenshinweise beachten. |
| `data.lines[].base_total` | string | — | Geldbetrag; Text-/Ganzzahldarstellung für Genauigkeit beibehalten. |
| `data.lines[].subtotal` | string | — | Geldbetrag; Text-/Ganzzahldarstellung für Genauigkeit beibehalten. |
| `data.lines[].promotion_amount` | string | — | Vorgangsspezifischer Wert für promotion amount. Rückgabetyp beibehalten und Verhaltenshinweise beachten. |
| `data.lines[].total` | string | — | Geldbetrag; Text-/Ganzzahldarstellung für Genauigkeit beibehalten. |
| `data.lines[].total_minor` | integer | — | Ganzzahl in kleinster Währungseinheit: 1000 bedeutet 10.00 TRY/USD. |
| `data.discount_scope` | string | — | Vorgangsspezifischer Wert für discount scope. Rückgabetyp beibehalten und Verhaltenshinweise beachten. |
| `data.estimate_only` | boolean | — | Vorgangsspezifischer Wert für estimate only. Rückgabetyp beibehalten und Verhaltenshinweise beachten. |
| `data.stock_checked` | boolean | — | Preis/lokales Ergebnis allein garantiert weder Anbieter noch Bestand. |
| `data.purchase_available` | boolean | — | Verfügbarkeit nach Bedingungen/Berechtigungen; keine Bestands- oder Anbietergarantie. |
| `data.calculated_at` | string | — | Zeitstempel im vom API gelieferten Format; Beispieldaten sind synthetisch. |
| `meta` | object | — | Metadaten zu Anfragezuordnung und Datenquelle. |
| `meta.request_id` | string | — | Kennung dieser HTTP-Anfrage, kein Vorgangsschlüssel oder Bestell-ID. |
| `meta.phase` | string | — | Vorgangsspezifischer Wert für phase. Rückgabetyp beibehalten und Verhaltenshinweise beachten. |
| `meta.source` | string | — | Datenquelle; lokale Datensätze und Live-Anbieterabfragen sind unterschiedliche Nachweise. |

## Verhalten & wichtige Hinweise

- IDs aus products/catalog übernehmen. quote-Zeilen enthalten nur location_id, time_id, quantity. purchase erfordert zusätzlich purpose_id=201 und gewählte subpurpose_id.
- Für quote enthalten die Positionen keinen Verwendungszweck: location_id, time_id und quantity reichen aus. Die Zweckfelder sind bei purchase erforderlich.
- Verwenden Sie bis zu 20 verschiedene location_id unter einem product_id. Jedes Land erzeugt eine eigene Bestellung; der verknüpfte Einkauf wird in einer Rechnung behandelt. Mengenrabatte werden pro Land berechnet.

Authentifizierung und Validierung können eine Anfrage vor der Ausführung ablehnen. Beachten Sie die Fehlerreferenz und bewahren Sie request_id für den Support auf. Senden Sie niemals Schlüssel oder Passwörter.

[Fehler & Limits](https://docs.arnproxy.com/de/api-v1/errors)
