# API-documentatie

De LJPc reseller-API laat je domeinnamen en hosting volledig geautomatiseerd verkopen en beheren. Het is een REST-API die JSON teruggeeft over HTTPS. Registreer en verhuis domeinen, beheer DNS, bestel en lever hosting uit en beheer klantsites, precies zoals de meegeleverde boilerplate dat doet.

- Basis-URL: `https://ljpc-hosting.nl`
- Hostingpaden staan onder `/api/hosting/v1`, order- en productpaden onder `/api/v1`
- Alle bedragen zijn de prijs die jouw account bij ons betaalt, inclusief je valuepack, exclusief btw; als reseller bepaal je daarbovenop je eigen verkoopprijs

## Authenticatie

Elk verzoek authenticeert met de header `X-API-Key`. Er komt geen bearer-token of cookie aan te pas. Een ontbrekende of onbekende sleutel geeft HTTP 401 met een envelope-body.

```bash
curl -H "X-API-Key: <your-key>" \
  https://ljpc-hosting.nl/api/hosting/v1/tlds
```

**Toegang tot je sleutel.** LJPc stelt je sleutel in met precies de toegang die jouw integratie nodig heeft. Wil je aanpassen wat je sleutel mag doen, neem dan contact met ons op via support@ljpc.nl.

## Antwoordformaat

Vrijwel elk endpoint verpakt zijn payload in de standaard envelope. Lees `.data` voor de payload bij succes en `.message` voor de fouttekst bij een fout. Elk antwoord draagt ook een `X-Validation`-header (een korte JWT waarvan de `jti` overeenkomt met de body); die verifiëren is optioneel.

```json
// Succes (200 / 201 / 202)
{ "success": true, "jti": "<uuid>", "data": <payload> }

// Fout (4xx / 5xx)
{ "success": false, "jti": "<uuid>", "message": "<reason>" }
```

**Uitzondering: producten (RAW JSON).** De catalogus- en winkelwagen-endpoints van de order-module zijn openbaar (geen `X-API-Key`) en geven RAW JSON, niet de envelope. `GET /api/v1/products` geeft direct `{"products": [...]}` terug, zonder `success`, `jti` of `data`.

## Endpoints

### Domeinen en TLDs

#### GET /api/hosting/v1/tlds

Haalt de volledige verkoopbare TLD-catalogus op met indicatieve catalogus-lijstprijzen (EUR) per jaar. `price` is `null` wanneer de catalogusprijs niet beschikbaar is; `transfer_supported` geeft aan of de TLD een verhuizing met auth-code ondersteunt. Voor de exacte prijs van een specifiek domein inclusief je valuepack gebruik je `/domain-names/price`. Permissie: geen (geldige sleutel volstaat).

```bash
curl -H "X-API-Key: <your-key>" \
  https://ljpc-hosting.nl/api/hosting/v1/tlds
```

```json
200 OK
{ "success": true, "jti": "…", "data": [
  { "tld": "nl", "price": 3.88, "currency": "EUR", "transfer_supported": true },
  { "tld": "2000.hu", "price": 5, "currency": "EUR", "transfer_supported": true }
] }
```

#### GET /api/hosting/v1/domain-names/check

Controleert de beschikbaarheid van een domeinnaam. Het antwoord is een string per opgevraagd domein (bijvoorbeeld `available`). Een TLD die wij niet verkopen geeft `unknown`. Permissie: Check domain availability.

| Parameter | Type | Verplicht | Omschrijving |
|---|---|---|---|
| domain | query string | ja | De domeinnaam om te controleren. Een array is ook toegestaan. |

```bash
curl -H "X-API-Key: <your-key>" \
  "https://ljpc-hosting.nl/api/hosting/v1/domain-names/check?domain=example.nl"
```

```json
200 OK
{ "success": true, "jti": "…", "data": { "example.nl": "available" } }
```

#### GET /api/hosting/v1/domain-names/price

Geeft de exacte prijs van een domeinnaam voor jouw account, inclusief je valuepack, als geneste money-object per domein, plus een premium-vlag. Een onbekende TLD geeft `null` voor die sleutel. Permissie: Check domain price.

| Parameter | Type | Verplicht | Omschrijving |
|---|---|---|---|
| domain | query string | ja | De domeinnaam om op te vragen. Een array is ook toegestaan. |

```json
200 OK
{ "success": true, "jti": "…", "data": {
  "example.nl": {
    "premium": false,
    "price":     { "amount": "11.23", "currency": "EUR" },
    "price_eur": { "amount": "11.23", "currency": "EUR" }
  } } }
```

#### GET /api/hosting/v1/domain-names

Lijst van je eigen domeinnamen (eigenaargebonden), gepagineerd. Permissie: View domains and sites.

| Parameter | Type | Verplicht | Omschrijving |
|---|---|---|---|
| page | query int | nee | Paginanummer, standaard 1. |
| per_page | query int | nee | Aantal per pagina, max 100, standaard 25. |

```json
200 OK
{ "success": true, "jti": "…", "data": {
  "domains": [
    { "domain": "example.nl", "status": "active",
      "expires_at": "2027-07-02T16:37:57+02:00",
      "auto_renew": true, "transfer_lock": true }
  ],
  "total": 2, "page": 1, "per_page": 25 } }
```

#### GET /api/hosting/v1/domain-names/{domain}

Detail van een domein. Live informatie uit ons systeem wordt over de opgeslagen gegevens gelegd (met terugval op de opgeslagen rij wanneer ons systeem tijdelijk niet bereikbaar is). `status` kan een samengevoegde status zijn; behandel die als een ondoorzichtige waarde. Een vreemd domein geeft 404. Permissie: View domains and sites.

```json
200 OK
{ "success": true, "jti": "…", "data": {
  "domain": "example.nl", "status": "active",
  "expires_at": "2027-07-02T16:37:57+02:00",
  "nameservers": ["ns1.ljpc.network", "ns2.ljpc.network", "ns3.ljpc.network"],
  "auto_renew": true, "transfer_lock": true,
  "contact_handle": "apitest-owned-0001" } }
```

#### POST /api/hosting/v1/domain-names

Registreert een nieuwe domeinnaam op een eigen WHOIS-contact. De controlevolgorde weigert een niet-ondersteunde TLD, een duplicaat of een onbekende/vreemde handle voordat het domein in ons systeem wordt geregistreerd. Permissie: Register domains through the API.

| Parameter | Type | Verplicht | Omschrijving |
|---|---|---|---|
| domain | body string | ja | De te registreren domeinnaam. |
| contact_handle | body string | ja | Een eigen WHOIS-handle. |
| years | body int | nee | 1..10, standaard 1. |
| nameservers | body array | nee | 2..13 hostnames. |
| external_reference | body string | nee | Je eigen referentie. |

```bash
curl -X POST -H "X-API-Key: <your-key>" \
  -H "Content-Type: application/json" \
  -d '{"domain":"example.nl","contact_handle":"apitest-owned-0001","years":1}' \
  https://ljpc-hosting.nl/api/hosting/v1/domain-names
```

```json
201 Created
{ "success": true, "jti": "…", "data": {
  "domain": "example.nl", "status": "active",
  "message": "Domain registered successfully" } }

422 { "success": false, "jti": "…", "message": "Domain already exists" }
403 { "success": false, "jti": "…", "message": "Contact handle does not belong to you" }
```

#### POST /api/hosting/v1/domain-names/{domain}/transfer

Start de verhuizing van een domein met een auth-code naar een eigen WHOIS-contact. Levert een `pending_transfer`-status. Permissie: Transfer domains through the API.

| Parameter | Type | Verplicht | Omschrijving |
|---|---|---|---|
| domain | path | ja | Het te verhuizen domein. |
| auth_code | body string | ja | De EPP/auth-code. |
| contact_handle | body string | ja | Een eigen WHOIS-handle. |
| nameservers | body array | nee | Optionele nameservers. |
| external_reference | body string | nee | Je eigen referentie. |

```bash
curl -X POST -H "X-API-Key: <your-key>" \
  -H "Content-Type: application/json" \
  -d '{"auth_code":"<epp-code>","contact_handle":"apitest-owned-0001"}' \
  https://ljpc-hosting.nl/api/hosting/v1/domain-names/example.nl/transfer
```

```json
202 Accepted
{ "success": true, "jti": "…", "data": {
  "domain": "example.nl", "status": "pending_transfer",
  "message": "Domain transfer initiated successfully" } }
```

#### PATCH /api/hosting/v1/domain-names/{domain}

Wijzigt alleen de meegestuurde velden (only-changed). Een lege body geeft 422 "No changes to apply". Een vreemd domein geeft 404. Permissie: Edit own domains.

| Parameter | Type | Verplicht | Omschrijving |
|---|---|---|---|
| domain | path | ja | Het bij te werken domein. |
| nameservers | body array | nee | 2..4 hostnames. |
| auto_renew | body bool | nee | Automatische verlenging aan/uit. |
| transfer_lock | body bool | nee | Verhuisslot aan/uit. |
| whois_contact_handle | body string | nee | Een eigen WHOIS-handle. |

```bash
curl -X PATCH -H "X-API-Key: <your-key>" \
  -H "Content-Type: application/json" \
  -d '{"auto_renew":false}' \
  https://ljpc-hosting.nl/api/hosting/v1/domain-names/example.nl
```

```json
200 OK
{ "success": true, "jti": "…", "data": {
  "domain": "example.nl", "message": "Domain updated successfully" } }
```

#### GET /api/hosting/v1/domain-names/{domain}/authcode

Haalt de EPP/auth-code op voor een uitgaande verhuizing. 404 wanneer ons systeem geen code beschikbaar stelt of het domein niet van jou is. Permissie: View auth codes.

```json
200 OK
{ "success": true, "jti": "…", "data": {
  "domain": "example.nl", "auth_code": "<epp-code>" } }

404 { "success": false, "jti": "…", "message": "Auth code is not available for this domain" }
```

### WHOIS-contacten

Registrant-contacten. Een domein registreren of verhuizen vereist een eigen WHOIS-handle, dus maak of hergebruik hier eerst een contact.

#### GET /api/hosting/v1/contacts

Lijst van je WHOIS-contacten (eigenaargebonden), gepagineerd. Permissie: View WHOIS contacts through the API.

```json
200 OK
{ "success": true, "jti": "…", "data": {
  "contacts": [
    { "brand": "default", "name": "Owned Contact",
      "addressLine": ["Teststreet 1"], "postalCode": "1234AB",
      "city": "Testcity", "country": "NL", "email": "owned@example.com",
      "voice": "+31.612345678", "organization": "LJPc",
      "handle": "apitest-owned-0001" }
  ],
  "total": 1, "page": 1, "per_page": 25 } }
```

#### GET /api/hosting/v1/contacts/{handle}

Detail van een WHOIS-contact. Een vreemde handle geeft 404. Permissie: View WHOIS contacts through the API.

```json
200 OK
{ "success": true, "jti": "…", "data": {
  "brand": "default", "name": "Owned Contact",
  "addressLine": ["Teststreet 1"], "postalCode": "1234AB",
  "city": "Testcity", "country": "NL", "email": "owned@example.com",
  "voice": "+31.612345678", "organization": "LJPc",
  "handle": "apitest-owned-0001" } }

404 { "success": false, "jti": "…", "message": "Contact not found" }
```

#### POST /api/hosting/v1/contacts

Maakt een nieuw WHOIS-contact aan en geeft de nieuwe handle terug. Velden zijn snake_case. Permissie: Create WHOIS contacts through the API.

| Parameter | Type | Verplicht | Omschrijving |
|---|---|---|---|
| name | body string | ja | Naam van de contactpersoon. |
| address | body string | ja | Adres als enkele string. |
| country | body string | ja | ISO-2 landcode, precies 2 tekens. |
| organization | body string | nee | Organisatienaam. |
| postal_code | body string | nee | Postcode. |
| city | body string | nee | Plaats. |
| email | body string | nee | E-mailadres. |
| voice | body string | nee | Telefoon in E.164, bijvoorbeeld +31612345678 of +31.612345678. |

```bash
curl -X POST -H "X-API-Key: <your-key>" \
  -H "Content-Type: application/json" \
  -d '{"name":"Owned Contact","address":"Teststreet 1","postal_code":"1234AB",
       "city":"Testcity","country":"NL","email":"owned@example.com",
       "voice":"+31612345678"}' \
  https://ljpc-hosting.nl/api/hosting/v1/contacts
```

```json
201 Created
{ "success": true, "jti": "…", "data": { "handle": "<new-handle>" } }

422 { "success": false, "jti": "…", "message": "The country field must be 2 characters." }
```

#### PATCH /api/hosting/v1/contacts/{handle}

Werkt een WHOIS-contact bij. Eerst eigendom (404), dan validatie, dan de bijwerking in ons systeem. Alle velden zijn optioneel; niet-meegestuurde velden houden hun opgeslagen waarde. Permissie: Update WHOIS contacts through the API.

```bash
curl -X PATCH -H "X-API-Key: <your-key>" \
  -H "Content-Type: application/json" \
  -d '{"email":"new@example.com"}' \
  https://ljpc-hosting.nl/api/hosting/v1/contacts/apitest-owned-0001
```

```json
200 OK
{ "success": true, "jti": "…", "data": { "success": true } }
```

### DNS

Beheer de zone-records van een eigen domein. Het record heeft de vorm `{type, name, content, ttl, prio}`. Beheerde types zijn A, AAAA, CNAME, MX, TXT, SRV en CAA. NS-records worden niet beheerd: ze staan niet in de GET-output en blijven bij een PUT behouden. `name` is relatief aan de zone (`@` is de apex), `ttl` 60..86400, `prio` verplicht bij MX en SRV, anders `null`.

#### GET /api/hosting/v1/dns/zones/{domain}/records

Haalt de DNS-records van een eigen domein op. 404 wanneer het domein nog geen zone heeft (behandel dat als een lege set). Permissie: Manage DNS through the API.

```json
200 OK
{ "success": true, "jti": "…", "data": {
  "zone": { "domain": "example.nl", "source": "manual" },
  "records": [
    { "type": "A", "name": "@", "content": "192.0.2.10", "ttl": 3600, "prio": null }
  ] } }

404 { "success": false, "jti": "…", "message": "No DNS zone exists for this domain" }
```

#### PUT /api/hosting/v1/dns/zones/{domain}/records

Volledige vervanging van de beheerde recordtypes. Bij de eerste schrijfactie ontstaat een `source=manual` zone. Een lege array is een geldige leegmaak-actie. Een zone die door ons hostingpaneel wordt beheerd geeft 409. `synced` meldt of de wijziging onze DNS bereikte; `false` is normaal totdat het domein naar onze nameservers delegeert. Permissie: Manage DNS through the API.

| Parameter | Type | Verplicht | Omschrijving |
|---|---|---|---|
| domain | path | ja | Het eigen domein. |
| records | body array | ja | De complete gewenste recordset, verpakt in een `records`-sleutel. |

```bash
curl -X PUT -H "X-API-Key: <your-key>" \
  -H "Content-Type: application/json" \
  -d '{"records":[
        {"type":"A","name":"@","content":"192.0.2.10","ttl":3600,"prio":null},
        {"type":"MX","name":"@","content":"mail.example.nl","ttl":3600,"prio":10}
      ]}' \
  https://ljpc-hosting.nl/api/hosting/v1/dns/zones/example.nl/records
```

```json
200 OK
{ "success": true, "jti": "…", "data": {
  "zone": { "domain": "example.nl", "source": "manual" },
  "records": [ … ],
  "synced": false } }

422 { "success": false, "jti": "…", "message": "records.0: content must be a valid IPv4 address" }
409 { "success": false, "jti": "…", "message": "This zone is managed by our hosting control panel and cannot be edited through the API." }
```

### Hosting

Je hostingsites: opvragen, schijfgebruik uitlezen en een eenmalige SSO-URL naar het controlepaneel genereren. Alles is eigenaargebonden.

#### GET /api/hosting/v1/sites

Lijst van je hostingsites (eigenaargebonden), gepagineerd. Permissie: Show own sites through the API.

```json
200 OK
{ "success": true, "jti": "…", "data": {
  "sites": [
    { "id": 2019, "domain": "example.nl", "status": "active", "disk_space_gb": 10 }
  ],
  "total": 1, "page": 1, "per_page": 25 } }
```

#### GET /api/hosting/v1/sites/{id}

Detail van een site inclusief schijfgebruik. `disk_quota_bytes` is binaire GiB (`disk_space_gb` x 1024^3), `null` bij onbeperkt. `disk_used_bytes` en `email_used_bytes` zijn `null` als er nog geen verbruiksrij is. Een vreemde of onbekende id geeft 404 (geen enumeratie). Permissie: Show own sites through the API.

```json
200 OK
{ "success": true, "jti": "…", "data": {
  "id": 2019, "domain": "example.nl", "status": "active",
  "disk_space_gb": 10,
  "disk_used_bytes": 3221225472,
  "email_used_bytes": 1073741824,
  "disk_quota_bytes": 10737418240 } }
```

#### GET /api/hosting/v1/sites/{id}/login

Geeft een eenmalige SSO-URL naar het controlepaneel van de site. 204 wanneer er geen URL beschikbaar is. Eigenaargebonden: je logt alleen in op eigen of gedeelde sites. Permissie: Login to sites.

```json
200 OK
{ "success": true, "jti": "…", "data": {
  "url": "https://panel.ljpc.systems/sso?token=<single-use-token>" } }

204 No Content
403 { "success": false, "jti": "…", "message": "You don't have permission to login to this site" }
```

### Bestellingen

De productcatalogus en het plaatsen en volgen van bestellingen. Een bestelling wordt pending aangemaakt en asynchroon uitgeleverd; er zijn geen webhooks, dus poll `GET /api/v1/orders/{id}`.

#### GET /api/v1/products

Productcatalogus. RAW JSON, geen envelope. Zonder sleutel krijg je de lijstprijzen; stuur je je `X-API-Key` mee, dan zijn de prijzen de prijs die jouw account per hostingproduct bij ons betaalt, inclusief je valuepack. Optioneel filter met `?category=`. Prijzen zijn decimale strings; `monthly_price` is `null` bij yearly-only producten. Uitleverbare hostingpakketten hebben een `category_identifier` van de vorm `hosting_<N>gb`, `hosting_forward` of `hosting_dns`. Permissie: geen (openbaar).

```bash
curl https://ljpc-hosting.nl/api/v1/products
```

```json
200 OK
{ "products": [
  { "uuid": "afe29fe6-…", "name": "5GB hosting",
    "billing_period_type": "client_choice",
    "monthly_price": "4.99", "yearly_price": "49.90", "price": "4.99",
    "category": "hosting", "category_identifier": "hosting_5gb",
    "required_fields": [] },
  { "uuid": "f7b0f46f-…", "name": "Domein .media",
    "billing_period_type": "yearly_only",
    "monthly_price": null, "yearly_price": "44.99", "price": "44.99",
    "category": "domains", "category_identifier": "media",
    "required_fields": null }
] }
```

#### POST /api/v1/orders

Plaatst een bestelling via het beperkte pad. Dat pad forceert `status=pending`, `source=reseller-api`, `client_id=owner_id=handler_id=de aanroeper`, `send_invoice=false`, `send_quote=false`, `auto_deliver=true`, bewaart alleen `meta.external_reference` en herbouwt elke cart-item uit een whitelist met server-side prijzen. De order-id staat op `data.order.id`. Permissie: Create orders.

| Parameter | Type | Verplicht | Omschrijving |
|---|---|---|---|
| summary | body string | nee | Korte omschrijving van de bestelling. |
| meta.external_reference | body string | nee | Je eigen referentie (als enige meta bewaard). |
| order_lines | body array | ja | Regels met `{description, cart_item}`. Zie de vormen van cart_item hieronder. |

De `cart_item` van een orderregel heeft per type een eigen vorm:

- Hosting: `{"type":"hosting","product_uuid":"…","domain":"…","billing_period":"monthly|yearly"}` (`billing_period` alleen nodig bij `client_choice`-producten; `target_url` verplicht bij `hosting_forward`).
- Domein: `{"type":"domain","action":"register|transfer","sld":"…","tld":"…","auth_code":"…"}` (`auth_code` verplicht bij transfer).
- Eigen ruimte: `{"type":"hosting_own","space_id":<int>,"domain":"…"}` (prijs 0).

```bash
curl -X POST -H "X-API-Key: <your-key>" \
  -H "Content-Type: application/json" \
  -d '{
    "summary": "New hosting for example.nl",
    "meta": { "external_reference": "ORDER-1234" },
    "order_lines": [
      { "description": "5GB hosting",
        "cart_item": {
          "type": "hosting",
          "product_uuid": "afe29fe6-…",
          "domain": "example.nl",
          "billing_period": "monthly"
        } }
    ] }' \
  https://ljpc-hosting.nl/api/v1/orders
```

```json
201 Created
{ "success": true, "jti": "…", "data": { "order": {
  "id": 114, "status": "pending", "source": "reseller-api",
  "summary": "New hosting for example.nl",
  "order_lines": [
    { "description": "5GB hosting", "price": 4.99, "period": 1, "cart_item": { … } }
  ],
  "send_invoice": false, "send_quote": false, "auto_deliver": true,
  "total_price": 4.99, "needs_subscription": true, "needs_payment": true,
  "created_at": "…", "updated_at": "…" } } }

422 { "success": false, "jti": "…", "message": "Order line 1: unsupported cart item type 'hosting_upgrade'" }
403 { "success": false, "jti": "…", "message": "You can only create orders for yourself" }
```

#### GET /api/v1/orders/{id}

Statusdetail van een bestelling, inclusief provisioning per regel. `simple_status` (en `provisioning.overall`) is `pending`, `processing`, `completed` of `failed`. De per-regel `state` is `pending`, `done` of `failed`. Zodra een hostingregel klaar is, wordt `site_id` ingevuld; voer die door aan `GET /api/hosting/v1/sites/{id}`. Een vreemde order geeft 403, een onbekende 404. Permissie: View own orders.

```json
200 OK
{ "success": true, "jti": "…", "data": {
  "order": { "id": 110, "status": "pending", "source": "reseller-api",
             "order_lines": [ … ], "summary": "…", "total_price": 4.99 },
  "simple_status": "pending",
  "provisioning": {
    "overall": "pending",
    "lines": [
      { "index": 0, "type": "hosting", "state": "pending", "site_id": null, "domain": null },
      { "index": 1, "type": "domain",  "state": "pending", "site_id": null, "domain": null }
    ] } } }
```

## Werkstromen

### Een domein registreren

1. Maak een WHOIS-contact aan (`POST /contacts`) of hergebruik een bestaande handle (`GET /contacts`).
2. Controleer beschikbaarheid en prijs (`GET /domain-names/check` en `/price`).
3. Registreer het domein (`POST /domain-names`) met `domain` en `contact_handle`.
4. Beheer daarna nameservers en DNS (`PATCH /domain-names/{domain}`, `PUT /dns/zones/{domain}/records`).

### Hosting bestellen en uitleveren

1. Zoek het product op (`GET /api/v1/products`) en kies de `product_uuid` van het pakket.
2. Plaats de bestelling (`POST /api/v1/orders`) met een hosting-`cart_item`.
3. Poll `GET /api/v1/orders/{id}` tot `simple_status` `completed` of `failed` is (geen webhooks).
4. Lees de `site_id` van de hostingregel uit `provisioning.lines`.
5. Gebruik de site: `GET /sites/{id}` voor verbruik, `GET /sites/{id}/login` voor SSO.

### DNS beheren (volledige vervanging)

1. Lees de huidige set (`GET /dns/zones/{domain}/records`). 404 betekent nog geen zone; behandel dat als leeg.
2. Bouw de complete gewenste recordset op (alleen beheerde types; NS blijft automatisch behouden).
3. Vervang alles met `PUT /dns/zones/{domain}/records` en een `{"records":[…]}`-body (een lege array maakt leeg).
4. Controleer `synced` in het antwoord (informatief; blijft `false` tot het domein naar onze nameservers delegeert).

**Asynchrone uitlevering.** Uitlevering gebeurt asynchroon en er zijn geen webhooks. Poll `GET /api/v1/orders/{id}` tot `simple_status` `completed` of `failed` is en lees dan de site via de `site_id` van de regel. In productie draait er een wachtrij-worker die de bestellingen uitlevert.

**Uitleveren-eerst facturatie.** Het beperkte orderpad zet `auto_deliver=true` en `send_invoice=false`: de dienst wordt eerst uitgeleverd en daarna via een abonnement gefactureerd (`needs_subscription` en `needs_payment` in het antwoord wijzen op die opvolging). Je betaalt de prijs van je account inclusief je valuepack; je eigen verkoopprijs bepaal je zelf.

## Aandachtspunten

- **Inloggen is eigenaargebonden.** SSO logt alleen in op je eigen of gedeelde sites.
- **Onbekende TLD geeft "unknown".** Voor een TLD die wij niet verkopen geeft `/check` de waarde `unknown` en `/price` `null`. Behandel dat als niet-verkoopbaar.
- **Uitleveren-eerst abonnementsfacturatie.** Bestellingen worden uitgeleverd zonder dat er een factuur of offerte wordt verstuurd; de facturatie loopt daarna via een abonnement.
- **Prijzen zijn inclusief je valuepack.** Alle prijzen uit de API zijn de prijs die jouw account bij ons betaalt, inclusief je valuepack (excl. btw). Als reseller bepaal je daarbovenop zelf de verkoopprijs voor je klant.

## Referentie-implementatie

Een volledige voorbeeldintegratie tegen deze API (domeinen, DNS, hosting bestellen en uitleveren) staat in de hosting-panel boilerplate: https://github.com/LJPc-solutions/HostingPanelBoilerplate


---

## Contact

- LJPc hosting, Dr. A.F. Philipsweg 15F, 9403 AC Assen, Nederland
- Telefoon: 085 130 6429
- E-mail: support@ljpc.nl
- Deze pagina: https://ljpc-hosting.nl/api-documentatie
