# Tambah IP yang diizinkan

`POST /account/api/v1/proxies/authorized-ips/add`

## Otorisasi

`Authorization: Bearer YOUR_ARNPROXY_API_KEY`

`Accept: application/json`

Izin yang diperlukan: `proxy_management`

`Content-Type: application/json`

`Idempotency-Key` · 16–100 huruf, angka, _ atau -. Simpan dan gunakan nilai yang sama untuk operasi yang sama.

## Parameter

| Nama | Tipe | Wajib / Bersyarat | Nilai bawaan | Keterangan |
|---|---|---|---|---|
| `Idempotency-Key` (header) | string | Wajib | — | 16–100 huruf/angka/_/-. Pertahankan nilai untuk operasi/status; jangan pakai lagi dengan isi berbeda. |
| `proxy_id` (body) | integer | Wajib | — | ID catatan proxy aktif milik sendiri; 1–2147483647. |
| `ip` (body) | string | Wajib | — | Alamat IP publik. Periksa authorized_ip_families dalam respons proxy_access untuk keluarga IP yang didukung. Hanya izin IP yang Anda tambahkan melalui API sendiri yang dapat dihapus. |
| `expected_revision` (body) | string | Wajib | — | revision dari pembacaan cakupan/pengaturan terkait: 64 karakter heksadesimal kecil. |
| `terms` (body) | boolean | Wajib | — | Persetujuan harus berupa boolean JSON true, bukan string "true". |

## 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_id": "YOUR_PROXY_ID",
  "ip": "YOUR_PUBLIC_IPV4",
  "expected_revision": "FROM_SCOPE_REVISION",
  "terms": false
}
```

## 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 \
    --header 'Idempotency-Key: YOUR_SAVED_OPERATION_KEY' \
    --request POST --header 'Content-Type: application/json' \
    --data-binary @request.json \
    'https://www.arnproxy.com/account/api/v1/proxies/authorized-ips/add'
```

### python

```python
import os, requests

headers = {"Authorization": "Bearer " + os.environ["ARNPROXY_API_KEY"]}
headers["Idempotency-Key"] = "YOUR_SAVED_OPERATION_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/proxies/authorized-ips/add",
    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}` };
headers['Idempotency-Key'] = 'YOUR_SAVED_OPERATION_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/proxies/authorized-ips/add", {
  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[] = 'Idempotency-Key: YOUR_SAVED_OPERATION_KEY';
$headers[] = 'Content-Type: application/json';
$ch = curl_init('https://www.arnproxy.com/account/api/v1/proxies/authorized-ips/add');
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/proxies/authorized-ips/add", body)
  if err != nil { panic(err) }
  req.Header.Set("Authorization", "Bearer "+os.Getenv("ARNPROXY_API_KEY"))
  req.Header.Set("Idempotency-Key", "YOUR_SAVED_OPERATION_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/proxies/authorized-ips/add");
request.Headers.Authorization = new AuthenticationHeaderValue(
    "Bearer", Environment.GetEnvironmentVariable("ARNPROXY_API_KEY"));
request.Headers.Add("Idempotency-Key", "YOUR_SAVED_OPERATION_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/proxies/authorized-ips/add"))
    .header("Authorization", "Bearer " + System.getenv("ARNPROXY_API_KEY"))
    .header("Accept", "application/json")
    .header("Idempotency-Key", System.getenv("ARNPROXY_OPERATION_KEY"))
    .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, 202

```json
{
  "ok": true,
  "data": {
    "state": "completed",
    "action": "ip_add",
    "proxy_ids": [
      12345
    ],
    "reason_code": null,
    "replayed": false,
    "provider_write_steps_sent": 1,
    "resume_available": false,
    "primary_credentials_locked": true,
    "credentials_returned": false,
    "balance_changed": false,
    "proxy_expiry_changed": false,
    "authorization_scope": "upstream_order",
    "shared_order_effects_accepted": true,
    "grant_state": "active"
  },
  "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.state` | string | — | Status catatan/operasi. accepted bukan terkirim; completed bukan tes koneksi. |
| `data.action` | string | — | Nilai khusus operasi untuk action. Pertahankan tipe yang dikembalikan dan baca catatan perilaku. |
| `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.reason_code` | string|null | — | Kode alasan tetap atau null, bukan teks kesalahan penyedia mentah. |
| `data.replayed` | boolean | — | Hasil tersimpan dari operasi sama, bukan bukti debit/tindakan baru. |
| `data.provider_write_steps_sent` | integer | — | Nilai khusus operasi untuk provider write steps sent. Pertahankan tipe yang dikembalikan dan baca catatan perilaku. |
| `data.resume_available` | boolean | — | Izin melanjutkan langkah belum dikirim; jangan ulang otomatis jika false. |
| `data.primary_credentials_locked` | boolean | — | Nilai khusus operasi untuk primary credentials locked. Pertahankan tipe yang dikembalikan dan baca catatan perilaku. |
| `data.credentials_returned` | boolean | — | Nilai khusus operasi untuk credentials returned. Pertahankan tipe yang dikembalikan dan baca catatan perilaku. |
| `data.balance_changed` | boolean | — | Dampak yang dilaporkan; pengaturan perpanjangan otomatis dapat menimbulkan debit terpisah kelak. |
| `data.proxy_expiry_changed` | boolean | — | Dampak yang dilaporkan; pengaturan perpanjangan otomatis dapat menimbulkan debit terpisah kelak. |
| `data.authorization_scope` | string | — | Cakupan otorisasi; operasi pesanan/paket dapat memengaruhi penetapan lain. |
| `data.shared_order_effects_accepted` | boolean | — | Nilai khusus operasi untuk shared order effects accepted. Pertahankan tipe yang dikembalikan dan baca catatan perilaku. |
| `data.grant_state` | string | — | Status pemberian IP. Penghapusan dapat memiliki grant_state=none; pemberian induk dicabut terpisah. |
| `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

- Tindakan dapat berlaku pada seluruh grup otorisasi, misalnya pesanan atau paket, bukan hanya proxy terpilih. Periksa proxy_ids, authorization_scope, dan may_affect_other_proxies sebelum melanjutkan. Ambil revision baru jika cakupan berubah.
- Penghapusan hanya untuk pemberian IP oleh API akun ini. IP administrator/pengguna lain tidak dapat dihapus. Pemberian IP mengikuti pemeriksaan kedaluwarsa terpisah.
- Timeout/5xx bukan bukti perubahan gagal. Gunakan Idempotency-Key awal untuk status. Jangan ulang dengan kunci baru; GET tidak mengirim ulang perubahan.
- Daftar izin di Akun saya → API menentukan alamat yang boleh menggunakan kunci API dan dikelola dari halaman akun. IP resmi proxy menentukan alamat yang boleh terhubung ke proxy. Kedua pengaturan ini tidak saling mengubah.

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)

[Lacak operasi yang sama: Periksa operasi akses](https://docs.arnproxy.com/id/api-v1/proxies/access/status)
