HTTP API
https://api.anchoredip.com/api/. Everything the dashboard does, it does through this — there is no private API behind it.Authentication
There is none, in the usual sense. A lease has an access token, returned once when you order, and it appears in the URL of every call about that lease. No account, no OAuth, no key rotation.
Plans
GET /api/plans/response
[
{
"slug": "solo",
"name": "Solo",
"monthly_price_usd": "19.00",
"term_price_usd": "19.00",
"term_days": 30,
"trial_days": 0,
"included_ipv4": 1,
"included_ipv6": 1,
"included_tunnels": 2,
"requires_verification": false,
"payment_methods": [{ "value": "card", "name": "Card", "detail": "…" }]
}
]Read prices from here rather than hardcoding them. The headline monthly_price_usd is per month whatever the term; term_price_usd is what is actually charged. On an annual plan they differ by a factor of twelve.
Order a lease
POST /api/leases/
Content-Type: application/json
{
"plan": "trial",
"organization_name": "Example GmbH",
"country": "DE",
"billing_email": "ops@example.com"
}response — free or trial plan
{ "access_token": "884c53fe-…", "status": "active" }response — paid plan
{
"access_token": "69c81e11-…",
"status": "pending",
"amount_usd": "19.00",
"payment_reference": "AIP-00021",
"payment_methods": [ … ]
}Limited to five orders an hour from one address. A trial is one per billing email; a second is refused with a 400 that names the paid plans, which need no approval.
Read a lease
GET /api/leases/{access_token}/Returns status, the addresses held, every tunnel with its last handshake, what is owed, and the full billing history with a link to each invoice. This is what the dashboard renders.
Create a tunnel
POST /api/leases/{access_token}/tunnels/
{
"transport": "wireguard", // or "amneziawg"
"routing_mode": "source", // "source" | "full" | "destinations"
"destinations": [], // required with "destinations", refused without
"label": "eu-worker-1"
}response
{
"tunnel": {
"id": 42,
"transport": "wireguard",
"routing_mode": "source",
"label": "eu-worker-1",
"private_address": "10.128.4.7"
},
"ready_in_seconds": 60,
"config": "[Interface]\nPrivateKey = …",
"filename": "anchoredip-42.conf",
"warning": "This configuration contains your private key and is shown only once. Save it now."
}The id you revoke with is tunnel.id, not a top-level field.
Pick source for a Linux host with wg-quick and full for anything else — a source-routed config cannot work in a graphical client. See routing modes.
Revoke a tunnel
DELETE /api/leases/{access_token}/tunnels/{tunnel_id}/Frees the slot immediately. Meant to be callable from a shutdown hook: a container that revokes its own peer on exit will not exhaust your allowance with ghosts.
301, and a client that does not follow redirects reports no error while the peer stays exactly where it was.Reverse DNS
GET /api/leases/{access_token}/rdns/
POST /api/leases/{access_token}/rdns/
{ "address": "194.0.108.99", "hostname": "mail.example.com" }An empty hostname removes the record. Live within about a second — it is a row in our nameserver, not a ticket to somebody else.
Payment and renewal
POST /api/leases/{access_token}/renew/ { "plan": "solo" }
POST /api/leases/{access_token}/pay/ { "method": "card" }
POST /api/leases/{access_token}/pay/ { "method": "bank_transfer" }
GET /api/leases/{access_token}/invoice/?number=AIP-2026-0003renew without a plan renews the current one; a trial has none to renew into, so it answers 400 with the plans it can move to. Naming a plan converts the lease and keeps the addresses, which is the entire reason the trial runs on real space.
Which methods a plan accepts comes back with the plan itself on GET /api/plans/, in payment_methods. A bank transfer is offered only where the invoice is larger than the fee to send it, so on the smaller plans the card is the only entry in that list.
Recover access
POST /api/auth/link/ { "email": "ops@example.com" }
POST /api/auth/redeem/ { "key": "…from the email…" }The first emails a one-time link, valid thirty minutes; the second exchanges it for every lease billed to that address. An address we do not bill gets exactly the same answer as one we do.
Errors
Ordinary HTTP. 400 for a request that cannot be satisfied as written, 404 for an access token we do not know, 409 when the request is well formed but the state does not allow it — a tunnel past the number your plan includes, or a renewal on a lease that has ended — 429 when throttled. The body carries detail with a sentence you can show a person.