# Harga perpanjangan

`POST /account/api/v1/renewals/quote`

## Otorisasi

`Authorization: Bearer YOUR_ARNPROXY_API_KEY`

`Accept: application/json`

Izin yang diperlukan: `read`

`Content-Type: application/json`

## Parameter

| Nama | Tipe | Wajib / Bersyarat | Nilai bawaan | Keterangan |
|---|---|---|---|---|
| `proxy_ids` (body) | integer[] | Wajib | — | 1–1000 ID proxy unik milik sendiri; jangan campur tipe produk saat perlu cakupan/harga bersama. Beberapa operasi lebih ketat. |
| `time_id` (body) | integer | Wajib | — | ID periode/paket GB dari katalog/options terkait, bukan jumlah hari/GB. |
| `promo_code` (body) | string | Opsional | `""` | Promo opsional, maksimal 100 byte. Pertahankan sama antara harga dan pembelian/perpanjangan. |

## Isi permintaan

Ganti YOUR_/FROM_ dengan nilai katalog, kutipan harga, atau cakupan terkait. Persetujuan pada contoh tetap false; setujui operasi nyata secara sengaja.

```json
{
  "proxy_ids": [
    "YOUR_PROXY_ID"
  ],
  "time_id": "FROM_RENEWAL_OPTIONS",
  "promo_code": ""
}
```

## Contoh permintaan

### 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/renewals/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/renewals/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/renewals/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/renewals/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/renewals/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/renewals/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/renewals/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());
```

## Respons · HTTP 200

```json
{
  "ok": true,
  "data": {
    "product_id": 5,
    "currency": "TRY",
    "proxy_ids": [
      12345
    ],
    "quantity": 1,
    "selection_hash": "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
    "time_id": 101,
    "period": "7 days",
    "days": 7,
    "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",
        "quantity": 1,
        "base_unit_price": "10.0000",
        "unit_price": "10.0000",
        "quantity_discount_rate": "0.00",
        "total_minor": 1000,
        "total": "10.00"
      }
    ],
    "proxies": [
      {
        "id": 12345,
        "location_id": 10,
        "last_service_date": "2030-02-01",
        "projected_last_service_date": "2030-02-08",
        "total": "10.00",
        "total_minor": 1000
      }
    ],
    "discount_scope": "country",
    "timezone": "Europe/Istanbul",
    "estimate_only": true,
    "renewal_available": true,
    "provider_checked": false,
    "calculated_at": "2030-01-01T12:00:00+00:00"
  },
  "meta": {
    "request_id": "000000000000000000000001",
    "phase": "public_v1",
    "source": "arnproxy_records"
  }
}
```

| Nama | Tipe | Bersyarat | Keterangan |
|---|---|---|---|
| `ok` | boolean | — | Penanda berhasil; jika false, periksa error.code. |
| `data` | object | — | Hasil khusus operasi; contoh bersifat ilustratif dan sintetis. |
| `data.product_id` | integer | — | ID lokasi atau tipe produk katalog lokal. |
| `data.currency` | string | — | Mata uang transaksi akun: TRY atau USD. |
| `data.proxy_ids` | array | — | ID proxy dalam cakupan yang terlihat bagi akun ini. |
| `data.proxy_ids[]` | integer | — | ID proxy dalam cakupan yang terlihat bagi akun ini. |
| `data.quantity` | integer | — | Jumlah proxy terpilih atau dipesan. |
| `data.selection_hash` | string | — | Sidik kesegaran untuk disalin tanpa perubahan ke perubahan/konfirmasi harga terkait. |
| `data.time_id` | integer | — | ID periode/paket GB lokal, bukan jumlah hari atau GB. |
| `data.period` | string | — | Nama periode katalog yang mudah dibaca. |
| `data.days` | integer | — | Durasi paket dalam hari, terpisah dari jumlah trafik paket GB. |
| `data.base_total` | string | — | Nominal uang; pertahankan representasi string/integer untuk presisi. |
| `data.quantity_discount_amount` | string | — | Nilai khusus operasi untuk quantity discount amount. Pertahankan tipe yang dikembalikan dan baca catatan perilaku. |
| `data.subtotal` | string | — | Nominal uang; pertahankan representasi string/integer untuk presisi. |
| `data.promotion` | object | — | Nilai khusus operasi untuk promotion. Pertahankan tipe yang dikembalikan dan baca catatan perilaku. |
| `data.promotion.code` | string | — | Nilai khusus operasi untuk code. Pertahankan tipe yang dikembalikan dan baca catatan perilaku. |
| `data.promotion.rate` | string | — | Nilai khusus operasi untuk rate. Pertahankan tipe yang dikembalikan dan baca catatan perilaku. |
| `data.promotion.amount` | string | — | Nominal uang; pertahankan representasi string/integer untuk presisi. |
| `data.total` | string | — | Nominal uang; pertahankan representasi string/integer untuk presisi. |
| `data.total_minor` | integer | — | Integer satuan uang terkecil: 1000 berarti 10.00 TRY/USD. |
| `data.lines` | array | — | Nilai khusus operasi untuk lines. Pertahankan tipe yang dikembalikan dan baca catatan perilaku. |
| `data.lines[]` | object | — | Nilai khusus operasi untuk lines. Pertahankan tipe yang dikembalikan dan baca catatan perilaku. |
| `data.lines[].location_id` | integer | — | ID lokasi atau tipe produk katalog lokal. |
| `data.lines[].country` | string | — | Nilai khusus operasi untuk country. Pertahankan tipe yang dikembalikan dan baca catatan perilaku. |
| `data.lines[].quantity` | integer | — | Jumlah proxy terpilih atau dipesan. |
| `data.lines[].base_unit_price` | string | — | Nilai khusus operasi untuk base unit price. Pertahankan tipe yang dikembalikan dan baca catatan perilaku. |
| `data.lines[].unit_price` | string | — | Nilai khusus operasi untuk unit price. Pertahankan tipe yang dikembalikan dan baca catatan perilaku. |
| `data.lines[].quantity_discount_rate` | string | — | Nilai khusus operasi untuk quantity discount rate. Pertahankan tipe yang dikembalikan dan baca catatan perilaku. |
| `data.lines[].total_minor` | integer | — | Integer satuan uang terkecil: 1000 berarti 10.00 TRY/USD. |
| `data.lines[].total` | string | — | Nominal uang; pertahankan representasi string/integer untuk presisi. |
| `data.proxies` | array | — | Nilai khusus operasi untuk proxies. Pertahankan tipe yang dikembalikan dan baca catatan perilaku. |
| `data.proxies[]` | object | — | Nilai khusus operasi untuk proxies. Pertahankan tipe yang dikembalikan dan baca catatan perilaku. |
| `data.proxies[].id` | integer | — | ID catatan ARNPROXY terkait; gunakan alih-alih ID internal penyedia. |
| `data.proxies[].location_id` | integer | — | ID lokasi atau tipe produk katalog lokal. |
| `data.proxies[].last_service_date` | string | — | Hari layanan terakhir: saat ini, sebelumnya, atau proyeksi harga. Proyeksi tidak memperpanjang. |
| `data.proxies[].projected_last_service_date` | string | — | Hari layanan terakhir: saat ini, sebelumnya, atau proyeksi harga. Proyeksi tidak memperpanjang. |
| `data.proxies[].total` | string | — | Nominal uang; pertahankan representasi string/integer untuk presisi. |
| `data.proxies[].total_minor` | integer | — | Integer satuan uang terkecil: 1000 berarti 10.00 TRY/USD. |
| `data.discount_scope` | string | — | Nilai khusus operasi untuk discount scope. Pertahankan tipe yang dikembalikan dan baca catatan perilaku. |
| `data.timezone` | string | — | Zona waktu kolom tanggal terkait; null berarti belum terverifikasi. |
| `data.estimate_only` | boolean | — | Nilai khusus operasi untuk estimate only. Pertahankan tipe yang dikembalikan dan baca catatan perilaku. |
| `data.renewal_available` | boolean | — | Ketersediaan sesuai syarat/izin, bukan jaminan stok atau penyedia. |
| `data.provider_checked` | boolean | — | Harga/hasil lokal sendiri bukan jaminan penyedia atau stok. |
| `data.calculated_at` | string | — | Stempel waktu sesuai representasi API; tanggal contoh sintetis. |
| `meta` | object | — | Metadata korelasi permintaan dan sumber data. |
| `meta.request_id` | string | — | ID korelasi permintaan HTTP ini, bukan kunci operasi atau ID pesanan. |
| `meta.phase` | string | — | Nilai khusus operasi untuk phase. Pertahankan tipe yang dikembalikan dan baca catatan perilaku. |
| `meta.source` | string | — | Sumber data; catatan lokal dan kueri penyedia langsung merupakan bukti berbeda. |

## Perilaku & catatan penting

- Perpanjangan memakai harga dan saldo situs yang ada. Salin nominal, hari, dan hash pilihan dari renewal_quote yang sama. Tidak mengaktifkan perpanjangan otomatis.
- Proxy dalam satu permintaan perpanjangan harus memiliki jenis produk yang sama. Diskon dihitung per negara berdasarkan jumlah yang dipilih, bukan gabungan semua negara.

Autentikasi dan validasi dapat menolak permintaan sebelum dijalankan. Lihat referensi kesalahan dan simpan request_id untuk dukungan. Jangan kirim kunci atau kata sandi.

[Kesalahan & batas](https://docs.arnproxy.com/id/api-v1/errors)
